FPGA(Verilog) - 在仿真中工作但不在FPGA上工作

时间:2016-06-20 17:10:25

标签: verilog fpga

以下代码实现(或应实现)7段驱动程序,该驱动程序从某些开关读取值并显示4 7段中的值。 模拟工作正常,但是当它在FPGA中运行时,7段显示器会显示一段时间,然后没有任何段亮起。 我不知道为什么它不起作用。 另外,我实现了一个简单的计数器。当我在总是阻塞它的时候有“< =”,当我有“=”时它没有,但是在模拟中它同时适用于两者。 “< =”和“=”之间的区别只是“< =”并行运行,“=”依次运行?

我还应该说,如果不是将交换机的值发送到显示模块,而是发送一个常量值,它就可以工作。

display.v:

module display(
    input [15:0] count,
    output reg [6:0] seg,
    output dp,
    output [3:0] an,
    input clk
    );

reg [3:0] an_temp;
reg [6:0] rom [9:0];

initial
begin
    an_temp <= 1;
    rom[0] <= 'b1000000;
    rom[1] <= 'b1111001;
    rom[2] <= 'b0100100;
    rom[3] <= 'b0110000;
    rom[4] <= 'b0011001;
    rom[5] <= 'b0010010;
    rom[6] <= 'b0000010;
    rom[7] <= 'b1111000;
    rom[8] <= 'b0000000;
    rom[9] <= 'b0110000;
end

assign dp = 1;
assign an = ~an_temp;

wire [3:0] disp [3:0];

assign disp[0] = count % 10;
assign disp[1] = ((count - disp[0])/10) % 10;
assign disp[2] = ((count - disp[1]*10 - disp[0])/100) % 10;
assign disp[3] = ((count - disp[2]*100 - disp[1]*10 - disp[0])/1000) % 10;

always @ (posedge clk)
begin
    if (an_temp == 'b1000) an_temp = 1;
    else an_temp = an_temp = 1;
    case (an_temp)
        'b0001: seg <= rom[disp[0]];
        'b0010: seg <= rom[disp[1]];
        'b0100: seg <= rom[disp[2]];
        'b1000: seg <= rom[disp[3]];
        default: seg <= 'b1111111;
    endcase
end

endmodule

disp_clk.v:

module disp_clk(
    input clk,
    output disp_clk
    );

reg [31:0] count;

initial count = 0;

always @ (posedge clk)
begin
    count = count + 1;
    if (count == 400000) count = 0;
end

assign disp_clk = (count > 200000) ? 1 : 0;

endmodule

top.v:

module top(
    input clk,
    input [15:0] sw,
    output [6:0] seg,
    output dp,
    output [3:0] an
    );

wire disp_clk;

disp_clk disp_clk0(
    .clk(clk),
    .disp_clk(disp_clk)
    );

display disp0(
    .count(sw),
    .seg(seg),
    .dp(dp),
    .an(an),
    .clk(disp_clk)
    );

endmodule

谢谢

1 个答案:

答案 0 :(得分:0)

  

我还应该说,如果不是从中发送值,它是有效的   切换到显示模块我发送一个恒定值。

听起来你没有达到你的时间窗口。如果count是常量向量,则disp赋值应全部在综合中预先计算。否则,它们需要在运行中计算,并推断出必要的逻辑(这是相当慢的)。

((count - disp[2]*100 - disp[1]*10 - disp[0])/1000) % 10有一个乘数进入另一个师的一个师。人们希望这被推断为级联DSP,但是你应该检查你的资源报告以确保,并且作为一个额外的健全性检查,确保常量与交换信令的资源计数显示出差异。

如果你想不出更优化的逻辑,你可能需要对这些操作进行管道化。

  

&#34;&lt; =&#34;之间的区别和&#34; =&#34;只是&#34;&lt; =&#34;并行运行&#34; =&#34;按顺序?

是的,从某种意义上说。 <==分别指代非阻止阻止分配。

模拟器将计算每个时间步的逻辑分配。

对于非阻塞,计算右侧,如果逻辑上依赖于其他信号,则可以在时间步骤中稍后更新,然后在下一个时间步骤开始之前,左侧所有非阻塞分配的手侧分配给更新的右侧。

阻止分配中,模拟器将评估右侧并立即将其分配到左侧,这样其他逻辑阻止不会改变分配

您可以考虑这种顺序,但请记住,顺序性只是功能块中。如果您有两个始终在同一时间步执行相关依赖评估的块,则无法保证模拟器将首先评估哪个块,您可能会看到一些基于模拟器如何进行调度的奇怪行为。 / p>

最佳做法是对打算组合的行为(即always@(*))使用阻止分配,对那些打算连续的行为使用阻止分配(即always@(posedge Clock))。< / p>