我一直在尝试调试此代码,但我找不到错误。但是,它没有产生我期望的结果。这是代码:
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
此代码没有测试平台;它反而加载到DE0板上。我的想法是,当我按下按钮1时,总和应该增加1.按钮2将其递增10,按钮3将其递增100.然而,封装if-else
的{{1}}模块似乎造成了一些严重的问题。
例如,当我激活开关控制复位时,总和按预期变为0。但是,当我尝试使用三个按钮中的任何一个增加总和时,会添加一个随机数 - 而不是1,10或100.
我还尝试在reset
语句之前移动if-else
语句。出现了另一个问题。即使未激活开关,总和也会设置为0,就好像忽略了复位条件一样。但是,如果我激活开关,则LED会亮起。如果我将其关闭,则LED将停用。但是,无论开关的状态如何,总和将始终设置为0。但是,在这种情况下,如果我按住一个按钮,我会看到总和中添加了1,10或100。一旦我释放它,总和就会重置为0.
显然,我认为我的if-else声明有问题。我不确定为什么它没有像我预期的那样工作。基本上,逻辑如下:
请注意,最后两个模块很简单。 case
将二进制字符串bintoBCD
转换为其BCD等效值。然后sum
只是一个七段显示编码器。
答案 0 :(得分:3)
这取决于你想要的以下几行:
always @(btn or reset)
组合逻辑还是顺序(触发器)?
如果支持SystemVerilog, 组合使用always @*
或always_comb
。自动灵敏度列表表现为组合硬件确实减少了模拟不匹配。
同时使用=
阻止组合分配。
顺序使用always @(posedge clk or negedge rst)
之类的内容并使用<=
这将允许模拟与硬件匹配。
您发现它们可能来自sum <= sum + inc;
,然后是可选的重置语句。 <=
的使用在这里是不正确的,因为它是具有手动灵敏度列表的组合块。 <=
作业的安排可能会让一些事情失去作用。
目前正在考虑您可能期望的硬件:
always @* begin
sum = sum + 1;
end
反对你得到的:
always @(posedge clk or negedge rst_n) begin
if (~rst) begin
sum <= 'b0;
end
else begin
sum <= sum + 1;
end
end
我认为如果你为你的设计添加一个时钟并暗示一个计数器的触发器(总和),你将朝着正确的方向迈出一大步。
答案 1 :(得分:3)
此代码没有测试平台
首先:创建一个测试平台!它并不困难(你甚至可以做online),对于逻辑错误,在模拟中调试比迭代更快真正的硬件。
其次:您的代码中没有时钟。这是最高级别的吗? FPGA在异步设计方面并不擅长,特别是在您尝试存储状态时(在本例中为sum
)。目前尚不清楚Quartus会推断出什么 - 它可能已将您的一个输入连接到时钟网络。您应该在RTL查看器中检查合成设计并查看综合日志。
但是,当我尝试使用三个按钮中的任何一个增加总和时,会添加一个随机数
您是否正在对开关输入进行去抖动?如果您不是,那么按下每个按钮很可能会获得随机数量的切换。
请注意,此处的敏感度列表不正确 - 它也应包含sum
:
always @(btn or reset)
讽刺的是(鉴于我的开场评论)这不会影响合成,但会改变模拟中的行为。您最好使用always_comb
(或always @(*)
,如果您遇到Verilog)。
答案 2 :(得分:1)
正在显示一个随机数,因为sum
在btn
正在改变状态时不断增加。明确的开始和停止点必须明确。
尝试使用时钟对btn
进行采样。在组合块中分配inc
。如果past_btn
等于btn
,则将inc
指定为零。应在时钟模块中分配sum
。
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
始终制作测试台并在模拟中运行。逻辑错误和实现问题很难从FPGA调试。