概述
项目场景:
From a 1000 Hz clock, derive a 1 Hz signal, called OneHertz, that could be used to drive an Enable signal for a set of hour/minute/second counters to create a digital wall clock. Since we want the clock to count once per second, the OneHertz signal must be asserted for exactly one cycle each second. Build the frequency divider using modulo-10 (BCD) counters and as few other gates as possible. Also output the enable signals from each of the BCD counters you use (c_enable[0] for the fastest counter, c_enable[2] for the slowest).
The following BCD counter is provided for you. Enable must be high for the counter to run. Reset is synchronous and set high to force the counter to zero. All counters in your circuit must directly use the same 1000 Hz signal.
module bcdcount (
input clk,
input reset,
input enable,
output reg [3:0] Q
);`---
问题描述
从一个1000hz的时钟,派生一个1hz的信号,称为OneHertz,它可以用于驱动一组小时/分钟/秒计数器的Enable信号,以创建一个数字挂钟。因为我们希望时钟每秒计算一次,所以OneHertz信号必须每秒精确地断言一个周期。使用模10 (BCD)计数器和尽可能少的其他门来构建分频器。还要从您使用的每个BCD计数器输出启用信号(c_enable[0]用于最快的计数器,c_enable[2]用于最慢的计数器)。
以下BCD计数器为您提供。Enable值必须高,计数器才能运行。复位是同步的,设置高可以强制计数器归零。电路中的所有计数器必须直接使用相同的1000hz信号。
原因分析:
(c_enable[0]用于最快的计数器,c_enable[2]用于最慢的计数器)表明c_enable[0]是秒计数器的使能信号,c_enable[1]是分钟计数器的使能信号,c_enable[2]是小时计数器的使能信号。但大家请注意题目Counter1000,别被前面误导。其实就是一个个位到十位再到百位的进位而已。
注意事项:
always@()里面的敏感变量为,意思是说敏感变量由综合器根据always里面的输入变量自动添加,也就是所有变量都是敏感列表,不用自己考虑。一般always@(*)是指里面的语句是组合逻辑的。*代替了敏感变量。而always@(posedge clk)为时序逻辑,在考虑逻辑运算的同时还要考虑延时。
参考信息:
1.always@后面内容是敏感变量,always@()里面的敏感变量为,意思是说敏感变量由综合器根据always里面的输入变量自动添加,也就是所有变量都是敏感列表,不用自己考虑。 2.如果没有@,那就是不会满足特定条件才执行,而是执行完一次后立马执行下一次,一直重复执行,比如testbench里面产生50Mhz的时钟就(假设时间尺度是1ns)可以写成 always #25 CLK_50Mhz = ~CLK_50Mhz;
一般always@(*)是指里面的语句是组合逻辑的。代替了敏感变量。
而一般时序逻辑要写成always@(posedge clk or negedge rst)//时钟信号clk上升沿或者复位信号rst下降沿的时候执行always块内的代码。
assign 用于描述组合逻辑
always@(敏感事件列表) 用于描述时序逻辑
敏感事件 上升沿 posedge,下降沿 negedge,或电平
敏感事件列表中可以包含多个敏感事件,但不可以同时包括电平敏感事件和边沿敏感事件,也不可以同时包括同一个信号的上升沿和下降沿,这两个事件可以合并为一个电平敏感事件。
在新的verilog2001中“,”和“or”都可以用来分割敏感事件了,可以用“”代表所有输入信号,这可以防止遗漏。
合法的写法:
always@ *
always@ (posedge clk1,negedge clk2)
always@ (a or b)
`timescale 100ns/100ns //定义仿真基本周期为100ns
always #1 clk=~clk //#1代表一个仿真周期即100ns
所有的assign 和 always 块都是并行发生的!
并行块、顺序块
将要并行执行的语句写在
fork
//语句并行执行
join
将要顺序执行的语句写在
begin
//语句顺序执行
end
并行块和顺序块都可以写在
initial 或 always@ 之后,也就是说写在块中的语句是时序逻辑的
对assign之后不能加块,实现组合逻辑只能用逐句的使用assign
组合逻辑如果不考虑门的延时的话当然可以理解为瞬时执行的,因此没有并行和顺序之分,并行和顺序是针对时序逻辑来说的。值得注意的是所有的时序块都是并行执行的。initial块只在信号进入模块后执行1次而always块是由敏感事件作为中断来触发执行的。
2:assign 组合逻辑和always@()组合逻辑
verilog描述组合逻辑一般常用的有两种:assign赋值语句和always@()语句。两者之间的差别有:
1. 被assign赋值的信号定义为wire型,被always@()结构块下的信号定义为reg型,值得注意的是,这里的reg并不是一个真正的触发器,只有敏感列表为上升沿触发的写法才会综合为触发器,在仿真时才具有触发器的特性。
2. 另外一个区别则是更细微的差别:举个例子,
wire a;
reg b;
assign a = 1’b0;
always@()
b = 1’b0;
在这种情况下,做仿真时a将会正常为0, 但是b却是不定态。这是为什么?verilog规定,always@()中的是指该always块内的所有输入信号的变化为敏感列表,也就是仿真时只有当always@()块内的输入信号产生变化,该块内描述的信号才会产生变化,而像always@() b = 1’b0;
这种写法由于1’b0一直没有变化,所以b的信号状态一直没有改变,由于b是组合逻辑输出,所以复位时没有明确的值(不定态),而又因为always@(*)块内没有敏感信号变化,因此b的信号状态一直保持为不定态。事实上该语句的综合结果有可能跟assign一样(本人没有去尝试),但是在功能仿真时就差之千里了。
添加链接描述
解决方案:
module top_module (
input clk,
input reset,
output OneHertz,
output [2:0] c_enable
);
reg [3:0] q1;
reg [3:0] q2;
reg [3:0] q3;
always@(*)
if(reset == 1'b1)
begin
c_enable <= 3'b000;
OneHertz <= 1'b0;
end
else
begin
c_enable[0] <= 1'b1;
c_enable[1] <= (q1 == 4'd9) ? 1'b1 : 1'b0;
c_enable[2] <= ((q1 == 4'd9) && (q2 == 4'd9)) ? 1'b1 : 1'b0;
OneHertz <= ((q1 == 4'd9) && (q2 == 4'd9) && (q3 == 4'd9)) ? 1'b1 : 1'b0;
end
bcdcount bcdcount_inst0
(
.clk (clk ),
.reset (reset ),
.enable (c_enable[0] ),
.Q
(q1
)
);
bcdcount bcdcount_inst1
(
.clk (clk ),
.reset (reset ),
.enable (c_enable[1] ),
.Q
(q2
)
);
bcdcount bcdcount_inst2
(
.clk (clk ),
.reset (reset ),
.enable (c_enable[2] ),
.Q
(q3
)
);
endmodule
最后
以上就是幸福眼神为你收集整理的Exams/ece241 2014 q7b(Counter 1000)项目场景:问题描述原因分析:注意事项:参考信息:解决方案:的全部内容,希望文章能够帮你解决Exams/ece241 2014 q7b(Counter 1000)项目场景:问题描述原因分析:注意事项:参考信息:解决方案:所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复