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