If statement 如果Else语句产生不正确的结果,请重置
我一直在尝试调试这段代码,但找不到其中的错误。然而,它并没有产生我所期望的结果。代码如下:If statement 如果Else语句产生不正确的结果,请重置,if-statement,verilog,If Statement,Verilog,我一直在尝试调试这段代码,但找不到其中的错误。然而,它并没有产生我所期望的结果。代码如下: module countAdd( btn, reset, thousands, hundreds, tens, ones, led); //Port Assignments input [2:0] btn; input reset; output [0:7] thousands, hundreds, tens, ones; output reg led; //Internal
module countAdd( btn, reset, thousands, hundreds, tens, ones, led);
//Port Assignments
input [2:0] btn;
input reset;
output [0:7] thousands, hundreds, tens, ones;
output reg led;
//Internal Port Assignments
reg [15:0] sum;
wire [15:0] sumBCD;
reg [15:0] inc;
//Add some stuff
always @(btn or reset)
begin
//Determine which button is active
case(btn)
3'b110: inc <= 1;
3'b101: inc <= 10;
3'b011: inc <= 100;
default: inc <= 0;
endcase
//Add
sum <= sum + inc;
//Should we reset?
if(reset)
begin
sum <= 0;
led <= 1;
end
else
begin
led <= 0;
end
end
//translate sum to sumBCD
binToBCD translate (sum, sumBCD[15:12], sumBCD[11:8], sumBCD[7:4], sumBCD[3:0]);
//display results on SS display
ssFromBCD seg0 (sumBCD[3:0], ones);
ssFromBCD seg1 (sumBCD[7:4], tens);
ssFromBCD seg2 (sumBCD[11:8], hundreds);
ssFromBCD seg3 (sumBCD[15:12], thousands);
endmodule
module binToBCD(sum, thousands, hundreds, tens, ones);
//Port Assignments
input [15:0] sum;
output reg [3:0] thousands;
output reg [3:0] hundreds;
output reg [3:0] tens;
output reg [3:0] ones;
//Begin conversion
integer i;
always @(sum)
begin
//set 1000's, 100's, 10's, and 1's to 0
thousands = 4'd0;
hundreds = 4'd0;
tens = 4'd0;
ones = 4'd0;
for(i = 15; i >= 0; i=i-1)
begin
//Add 3 to columns >= 5
if(thousands >= 5)
thousands = thousands + 3;
if(hundreds >= 5)
hundreds = hundreds + 3;
if(tens >= 5)
tens = tens + 3;
if(ones >= 5)
ones = ones + 3;
//Shift left ones
thousands = thousands << 1;
thousands[0] = hundreds[3];
hundreds = hundreds << 1;
hundreds[0] = tens[3];
tens = tens << 1;
tens[0] = ones[3];
ones = ones << 1;
ones[0] = sum[i];
end
end
endmodule
module ssFromBCD(in, ssOut);
//Port Assignments
input [3:0] in;
output reg [0:7] ssOut;
always @(in)
begin
case(in)
4'b0000: ssOut = 8'b00000011;
4'b0001: ssOut = 8'b10011111;
4'b0010: ssOut = 8'b00100101;
4'b0011: ssOut = 8'b00001101;
4'b0100: ssOut = 8'b10011001;
4'b0101: ssOut = 8'b01001001;
4'b0110: ssOut = 8'b01000001;
4'b0111: ssOut = 8'b00011111;
4'b1000: ssOut = 8'b00000001;
4'b1001: ssOut = 8'b00011001;
default: ssOut = 8'b11111111;
endcase
end
endmodule
模块计数添加(btn、复位、千、百、十、一、led);
//港口分配
输入[2:0]btn;
输入复位;
输出[0:7]千、百、十、一;
输出reg led;
//内部端口分配
注册[15:0]和;
电线[15:0]sumBCD;
注册[15:0]公司;
//加些东西
始终@(btn或重置)
开始
//确定哪个按钮处于活动状态
案例(btn)
3'b110:inc这取决于您希望从以下行中得到什么:
always @(btn or reset)
组合逻辑还是顺序(触发器)
组合如果支持SystemVerilog,则使用始终@*
或始终梳
。自动灵敏度列表的作用与组合硬件一样,可以减少模拟不匹配
也可以使用=
阻塞分配进行组合运算
顺序使用类似于始终@(posedge clk或negedge rst)
的方法,并使用
此代码没有测试台
首先:创建一个测试台!这并不困难(您甚至可以做到),对于逻辑错误,在模拟中调试要比在真实硬件上迭代快得多
第二:代码中没有时钟。这是顶层吗?FPGA不太擅长异步设计,尤其是当您试图存储状态时(在本例中为sum
)。现在还不清楚Quartus会推断出什么——它可能已经将您的一个输入连接到了一个时钟网络。您应该在RTL查看器中检查综合设计,并查看综合日志
但是,当我尝试使用三个按钮中的任何一个来增加总和时,会添加一个随机数
您是否正在取消开关输入的抖动?如果你没有,那么很可能每次按下按钮都会得到随机数目的切换
请注意,您的敏感度列表在此不正确-它还应包括sum
:
always @(btn or reset)
具有讽刺意味的是(鉴于我的开场白),这不会影响合成,但会改变模拟中的行为。您最好使用始终梳
(或始终(*)如果您一直使用Verilog)。显示一个随机数,因为总和
不断递增,而btn
正在改变状态。清晰的起点和终点必须明确
尝试使用时钟对btn进行采样。在组合块中,分配inc
。如果pass_btn
等于btn
,则将inc
赋值为零<代码>总和
应在时钟块中分配
alwasy @* begin
if (past_btn == btn) inc = 'b0;
else begin
// case(btn) ...
end
end
always @(posedge clk) begin
past_btn <= btn;
if (!reset) sum <= 'b0;
else sum <= sum + inc;
end
alwasy@*开始
如果(过去的时间==btn)inc='b0;
否则开始
//案例(btn)。。。
终止
终止
始终@(posedge clk)开始
过去的时间应该是连续的。我最初有一个sum=sum+inc
,但当时也不起作用。我切换它只是为了看看它是否有任何影响。最终,这个项目将有一个时钟。事实上,它应该每秒钟递增一次,只要按钮和它的关联值处于活动状态。在我加上一个时钟之前,我一直想让它工作。不过我会试试你的建议。这块板上的按钮已经脱落了。我试试加一个钟。
always @(btn or reset)
alwasy @* begin
if (past_btn == btn) inc = 'b0;
else begin
// case(btn) ...
end
end
always @(posedge clk) begin
past_btn <= btn;
if (!reset) sum <= 'b0;
else sum <= sum + inc;
end
alwasy @* begin
if (past_btn == sync_btn) inc = 'b0;
else begin
// case(sync_btn) ...
end
end
always @(posedge clk) begin
sync_btn <= btn;
past_btn <= sync_btn;
if (!reset) sum <= 'b0;
else sum <= sum + inc;
end