新手问题:VHDL最佳实践/效率

新手问题:VHDL最佳实践/效率,vhdl,Vhdl,我最近开始自学VHDL。作为一名嵌入式系统程序员,语言本身及其结构并不是什么大问题。我的问题是开发直觉知识,如何将我的代码映射到硅上。当我为嵌入式处理器编写C代码时,我对代码如何翻译(编译)以及如何在处理器中运行有相当好的了解。这是我想要为我的VHDL创作开发的。 我正在阅读示例程序(我发现这通常不是一个好主意,因为它只向您展示了可以做什么,而不一定是应该如何做) 在此,我给出一个示例程序的片段,以及在我的C-brain将其塑造成我能更好理解的东西之后的相同片段 我的问题是,;“是否将我所做的转

我最近开始自学VHDL。作为一名嵌入式系统程序员,语言本身及其结构并不是什么大问题。我的问题是开发直觉知识,如何将我的代码映射到硅上。当我为嵌入式处理器编写C代码时,我对代码如何翻译(编译)以及如何在处理器中运行有相当好的了解。这是我想要为我的VHDL创作开发的。 我正在阅读示例程序(我发现这通常不是一个好主意,因为它只向您展示了可以做什么,而不一定是应该如何做)

在此,我给出一个示例程序的片段,以及在我的C-brain将其塑造成我能更好理解的东西之后的相同片段

我的问题是,;“是否将我所做的转化为在硅上更高效或更低效的实现。我是否违反了最佳实践。”

范例

    -- Create a delay pulse of 16us when a key is pressed
    PROCESS( clk, rst )
    BEGIN
        IF( NOT rst = '1' ) THEN
            cnt_delay <= "00000000000000000000";
            start_delaycnt <= '0';
        ELSIF( clk'EVENT AND clk='1' ) THEN
            IF( start_delaycnt = '1' ) THEN
                IF (cnt_delay /= "11000011010100000000") THEN   -- 800.000 -> cnt_delay pulse is 16us long
                    cnt_delay <= cnt_delay + "00000000000000000001";
                ELSE
                    cnt_delay <= "00000000000000000000";
                    start_delaycnt <= '0';
                END IF;
            ELSE
                IF( (NOT key_input='1') AND (cnt_delay = "00000000000000000000") ) THEN
                    start_delaycnt <= '1';
                END IF;
            END IF;
        END IF;
    END PROCESS;
——按键时产生16us的延迟脉冲
过程(时钟、rst)
开始
如果(不是rst='1'),则
cnt_延迟启动延迟
--ELSIF((非key_input='1')和(start_delaycnt='0'))然后
--在正向时钟边缘->执行工作
ELSIF(clk'事件和clk='1'),然后
--按键按下且当前未处于延迟状态->开始延迟
如果((非键输入='1')和(启动延迟='0')),则
start_delaycnt增加计数器
ELSIF((start_delaycnt='1')和(cnt_delay/=“11000011010100000000”))则--800.000->cnt_延迟脉冲为16ms长
cnt_延迟重置输出信号并重置计数器
ELSIF(start_delaycnt='1'),然后

cnt_delay将时钟进程视为中央处理单元。现在将“中心”替换为“分布式并行”,即类似于多个并行核

在您给出的示例中,延迟是通过计算时钟周期(本例中为800)实现的

条件测试IF(clk'事件和clk='1')在硅中创建正边缘检测电路。在这种情况下,它寻找clk信号的上升沿。然后,您需要决定在这些上升沿上执行什么,以实现您的计时流程


注意:负边缘检测是通过IF(clk'EVENT和clk='0')实现的。

是的,我理解语义。问题不在于它是做什么的,而在于它是如何合成成硅的。合成器是否会为两个代码段创建相同的逻辑。是我制作这个例子的方式,我是否不赞成。基本上,我正在尝试创建一种编程风格,并希望它与行业实践相结合。此代码使用50MHz运行的时钟计算800.000个时钟周期,产生16us延迟(50MHz/800.000=62.5kHz;1/62.5kHz=16us)。我想使用时钟的正边缘,因此使用clk'EVENT和clk='1'。传统上,你会说,在积极的边缘,这样做。为了使ELSIF的流动,我必须将其反转。基本上我是说,;如果你没有一个积极的优势,就不要做别的事情。时钟进程用于实现顺序逻辑。您的尝试忽略了时钟,因此它是组合逻辑。它在时钟边缘上什么都不做,所以它不会计算时钟周期。啊哈。如果我理解正确,可以反转信号电平,但不能反转事件属性。我应该在发布之前综合我的代码。刚做了,它抛出了一个错误“语句不可合成,因为它在not(时钟边缘)条件下不保持其值”(尴尬)
    -- Create a delay pulse of 16us when a key is pressed
    PROCESS( clk, rst )
    BEGIN
        -- in reset -> reset our output signal and reset the counter
        IF( NOT rst = '1' ) THEN
            cnt_delay <= "00000000000000000000";
            start_delaycnt <= '0';
-- Edit Fixed bug. Cannot invert EVENT attribute
--      -- No clock transition -> do nothing
--      ELSIF( NOT( clk'EVENT AND clk='1' ) ) THEN

--      -- Key pressed and not currently in a delay -> start the delay
--      ELSIF( (NOT key_input='1') AND (start_delaycnt = '0') ) THEN

        -- On positive clock edge -> do work
        ELSIF( clk'EVENT AND clk='1' ) THEN

            -- Key pressed and not currently in a delay -> start the delay
            IF( (NOT key_input='1') AND (start_delaycnt = '0') ) THEN

            start_delaycnt <= '1';

        -- If we are currently in a delay and we have not reached the end it yet -> increase the counter
        ELSIF( (start_delaycnt = '1') AND (cnt_delay /= "11000011010100000000") ) THEN  -- 800.000 -> cnt_delay pulse is 16ms long
            cnt_delay <= cnt_delay + "00000000000000000001";

        -- If we are currently in a delay and we have reached the end -> reset our output signal and reset the counter
        ELSIF( start_delaycnt = '1' ) THEN
            cnt_delay <= "00000000000000000000";
            start_delaycnt <= '0';
        END IF;

        END IF;

    END PROCESS;