Verilog,FPGA,使用统一寄存器 [英] Verilog, FPGA, use of an unitialized register

查看:127
本文介绍了Verilog,FPGA,使用统一寄存器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对我正在研究的AGC / SPI控制器的奇怪行为有疑问。以Xilinx Spartan 3e FPGA为目标,在Verilog中完成。控制器是FSM,它依赖于外部输入来启动。 FSM的状态存储在未显式初始化的 state_reg 中,因为我认为未初始化的寄存器将默认为零。当我实现控制器时,FSM将无法运行。监视SPI总线时,我没有任何活动。为了监视FSM,我将 state_reg 路由到了连接到LED组的输出总线。这就是 assign data_out = state_reg 行的工作。但是我发现,当我执行FSM时,如在SPI总线上观察到的那样,AGC / SPI控制器可以正确运行。似乎正在发生的事情是 state_reg 在初始化时处于不确定状态,因此FSM永远不会处于任何状态,因此它不会运行。但是通过将 state_reg 分配给输出,正如我期望的那样,它初始化为 00000000 。所以我的问题是,未初始化的寄存器是否应该假定值为0?通过为输出分配一个未初始化的寄存器,是否会迫使它看起来像是零?还是这里发生了我不理解的事情?下面是我的代码。我已经评论了将* state_reg **分配给输出线[7:0] data_out 的相关部分。我知道这是一个很长的问题,但是我实际上是在试图理解我应该期待的行为类型。谢谢。

I have a question about what seems to me odd behavior of an AGC/SPI controller I'm working on. It's done in Verilog, targeting a Xilinx Spartan 3e FPGA. The controller is a FSM that relies on external inputs to start. The state of the FSM is stored in state_reg which is not explicitly initialized, as I thought an uninitialized register would default to zero. When I implemented the controller the FSM would not run. Monitoring the SPI bus I observed no activity. To monitor the FSM i routed the state_reg to an output bus that went to an LED bank. That is what the line assign data_out = state_reg is doing. I found though that when I did this the FSM an AGC/SPI controller operated correctly as observed on the SPI bus. It seems that what is happening is that state_reg is in an undetermined state when it initializes and hence the FSM is never in any state so it doesn't run. But by assigning state_reg to an output it initialized to 00000000 as I expected it to do from the beginning. So my question is, is an uninitialized register supposed to assume a value of 0? By assigning an uninitialized register to an output, does that force it to assume zero as it seemed? Or is something else going on here that I don't understand? Below is my code. I've commented the relevant part where *state_reg** is assigned to output wire [7:0] data_out. I know this is a long question but I"m really trying to understand what type of behavior I should expect. Thanks.

  module agc_control
        (
            input wire [7:0] agc_data,
            input wire clk,
            input wire agc_start,
            input wire AMP_DO,
            output reg MOSI,
            output reg SCK,
            output reg CS_AMP,
            output wire inhibit_ADC,
            output wire [7:0] data_out  
         );

        //signals
        reg [4:0] state_reg,
        reg [2:

0] ampclkreg;
    reg ampclk;
    reg [7:0] agc_data_reg;
    reg agc_running;
    reg [7:0] data_out_reg;
    wire agc_done;




    //ampclk generation
    always @(posedge clk)
        begin
            ampclkreg = ampclkreg + 1;
            if (ampclkreg == 3)
                begin
                    ampclkreg = 0;
                    ampclk = ~ampclk;
                end
        end

    always @(posedge clk)
        begin
            if(agc_start == 1)
                begin
                    agc_running = 1'b1;
                    agc_data_reg = agc_data;
                end
            if(agc_done == 1)
                begin
                    agc_running = 1'b0;
                end
        end



    //FSM
    always @(posedge ampclk)
        begin
            if (agc_running == 0)
                begin
                    SCK = 0;
                    state_reg = 0;
                    CS_AMP = 1;
                end
            if (agc_running == 1)
                begin
                    case (state_reg)
                        0:  begin
                                CS_AMP = 1;
                                SCK = 0;
                                state_reg = 1;
                            end
                        1:  begin
                                CS_AMP = 0;
                                MOSI = agc_data_reg[7];
                                state_reg = 2;
                            end
                        2:  begin
                                SCK = 1;
                                state_reg = 3;
                            end
                        3:  begin
                                SCK = 0;
                                MOSI = agc_data_reg[6];
                                state_reg = 4;
                            end
                        4:  begin
                                SCK = 1;
                                state_reg = 5;
                            end
                        5:  begin
                                SCK = 0;
                                MOSI = agc_data_reg[5];
                                state_reg = 6;
                            end
                        6:  begin
                                SCK = 1;
                                state_reg = 7;
                            end
                        7:  begin
                                SCK = 0;
                                MOSI    = agc_data_reg[4];
                                state_reg = 8;
                            end
                        8:  begin
                                SCK = 1;
                                state_reg = 9;
                            end
                        9:  begin
                                SCK = 0;
                                MOSI = agc_data_reg[3];
                                state_reg = 10;
                            end
                        10:begin
                                SCK = 1;
                                state_reg = 11;
                            end
                        11:begin
                                SCK = 0;
                                MOSI = agc_data_reg[2];
                                state_reg = 12;
                            end
                        12:begin
                                SCK = 1;
                                state_reg = 13;
                            end
                        13:begin
                                SCK = 0;
                                MOSI = agc_data_reg[1];
                                state_reg = 14;
                            end
                        14:begin
                                SCK = 1;
                                state_reg = 15;
                            end
                        15:begin
                                SCK = 0;
                                MOSI = agc_data_reg[0];
                                state_reg = 16;
                            end
                        16:begin
                                SCK = 1;
                                state_reg = 17;
                            end
                        17:begin
                                CS_AMP = 1;
                                state_reg = 18;
                            end
                        18:begin
                                SCK = 0;
                                state_reg = 19;
                            end
                        19:begin
                                state_reg = 19;
                            end
                    default: state_reg = 19;
                endcase
            end
        end

    //retrieve previous vlaues
    always @(posedge clk)
    begin
        case(state_reg)
            2: begin
                    if (ampclkreg == 2)             
                        data_out_reg[7] = AMP_DO;
                end
            4: begin
                    if (ampclkreg == 2)
                        data_out_reg[6] = AMP_DO;
                end
            6: begin 
                    if (ampclkreg == 2)
                        data_out_reg[5] = AMP_DO;
                end
            8:  begin
                    if (ampclkreg == 2)
                        data_out_reg[4] = AMP_DO;
                end
            10:begin
                    if (ampclkreg == 2)
                        data_out_reg[3] = AMP_DO;
                end
            12:begin
                    if (ampclkreg == 2)
                        data_out_reg[2] = AMP_DO;
                end
            14:begin
                    if (ampclkreg == 2)
                        data_out_reg[1] = AMP_DO;
                end
            16:begin
                    if (ampclkreg == 2)
                        data_out_reg[0] = AMP_DO;
                end

        endcase
    end


    //output wire [7:0] data_out--to top module to drive 7 LEDs and display state_reg
    assign data_out =  state_reg;

    assign agc_done = (state_reg == 19);
    assign inhibit_ADC = (agc_running == 1);


    endmodule


推荐答案

我在FPGA的背景下回答(我在Xilinx FPGA方面经验最丰富);我不同意Tim的回答。

I answer in the context of FPGAs (I have most experience with Xilinx FPGAs); I disagree with Tim's answer.

对FPGA进行编程和初始化后,许多内部资源都会初始化为已知状态。这包括所有触发器和块ram。通过在整个设计中添加毯式重置逻辑,您可以 使之大大复杂,如果您可以另外依靠内部元素初始化为已知状态的话。高扇出的复位网络会使路由器的设计工作更加困难,而且由于选择的复位方式(尤其是异步复位方式),将设计映射到片中也很复杂。

When an FPGA is programmed and initialized, many internal resources are initialized to a known state. This includes all flip flops and block rams. By adding blanket reset logic throughout your design, you may make it significantly more complicated than it needs to be, if you could otherwise count on internal elements initializing to a known state. High fanout reset nets can make implementation of your design much more difficult for the router, and mapping your design into slices is also complicated by your choice of resets - especially asynchronous ones.

我的建议:


  • 对寄存器使用初始化值。仔细检查Xilinx XST文档中所使用的版本,以获取受支持的语法。与普遍持有的信念相反,在大多数情况下都会采用初始化值。这样做的附带好处是,芯片的初始状态将与仿真的初始状态匹配。

  • 仅重置必要的控制信号,并单独保留数据路径寄存器以进行更有效的映射(例如,将管线传输到移位寄存器中)。

这篇关于Verilog,FPGA,使用统一寄存器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆