正如我预测的那样,Verilog代码在模拟中运行,但在FPGA中没有

时间:2014-06-30 12:54:23

标签: verilog fpga xilinx hdl synthesis

我尝试编写UART发送器模块。它从数据[7:0]获取数据,然后通过Tx串行发送。我写了一个名为Tester的模块用于测试变送器。它像我预测的那样在Isim中模拟,但在Spartan-6中没有。我用振镜观察了Tx引脚,我只看到逻辑1.我无法检测到问题。我做错了什么?

module Tester(
clk,
data,
oclk,
Tx
);
input wire clk;
output reg [7:0] data;
output wire oclk;
output wire Tx;

assign oclk = clk;

initial begin
data<=8'b11001010;
end

UartTransmitter UT(.clk(clk),.data(8'b11001010),.Tx(Tx),.transmit(1'b1)); 

endmodule


module UartTransmitter(
//Inputs
clk,
reset,
data,
transmit,
//Output
Tx
);
input wire clk;
input wire reset;
input wire [7:0] data;
input wire transmit;
output reg Tx;

reg [16:0] counter;
reg durum;
reg s_durum;
reg sendbyone;
reg [10:0]buffer;
reg [3:0]nbitstransmitted;

parameter IDLE = 1'b0;
parameter TRANSMITTING = 1'b1;

initial begin
    counter=0;
    Tx=1;
    s_durum = IDLE;
    durum=IDLE;
    sendbyone=0;
    buffer=0;
    nbitstransmitted=0;
end

always @(posedge clk) begin
    counter<=counter+1;
    if(counter>=13019) begin
        counter<=0;
        sendbyone<=1;
    end else begin
        sendbyone<=0;
    end
    durum<=s_durum;
end


always @(*) begin
    s_durum=durum;
    if((durum==IDLE) && (transmit==1)) begin
    buffer={1'b1,^data,data,1'b0};
    s_durum=TRANSMITTING;
    end

    else if(durum==TRANSMITTING && (sendbyone==1)) begin
        if(nbitstransmitted<10) begin
            Tx=buffer[nbitstransmitted];
            nbitstransmitted=nbitstransmitted+1;
        end else if(nbitstransmitted==10)begin
            Tx=buffer[10];
            nbitstransmitted=0;
            s_durum=IDLE;
        end
    end
end

endmodule

1 个答案:

答案 0 :(得分:1)

bufferTxnbitstransmitted是推断锁存器。当无法保证变量在组合块(always @*)中赋值时,推断出锁存器。 buffer是一个简单的锁存器,因为控制逻辑来自触发器。在Tx更改为触发器后,nbitstransmitted将是简单的锁存器。主要问题是nbitstransmitted因为它有反馈。根据模拟中的当前设计,datadurum==TRANSMITTING && sendbyone会发生变化,nbitstransmitted会增加data。即使durum来自同一时钟域的触发器,在FPGA上也可能存在每个位的偏斜并触发多次更新。

复杂的闩锁容易出现竞争条件,占用大量区域。例如,我将提供代码复制到EDAplayground并使用Yosys 0.3.0进行综合。使用&#34;显示图表&#34;启用后,它将显示大量使用的门,并具有足够的锁存反馈。尝试运行 here (抱歉,我无法上传图表,也许其他人可以)

通过遵循已用于buffer的相同策略,解决方案很容易;创建下一个状态变量。坚持使用当前约定,使用具有Tx前缀的受尊重名称为nbitstransmitteds_always @*创建新变量。组合块(s_)将分配always @(posedge clk)信号,并应默认为受尊重的计数器部分。顺序块(s_)将按其受尊重的counter<=counter+1;分配触发器。触发器删除异步反馈并简化设计。为了更清晰的设计,我将else移到if(nbitstransmitted==10)条件并注释掉了reset。尝试运行 here


与该问题无关的其他说明:

未使用initial信号。我建议在顺序块中使用它并删除initial块。大多数FPGA支持{{1}},大多数ASIC不支持。我更喜欢在初始模块上使用复位信号,因为它允许重置设备而无需重启电源。只是一个建议。