【问题标题】:Hazards in the wave in systemverilogsystemverilog中wave中的危害
【发布时间】:2021-04-10 15:31:40
【问题描述】:

在使用 FSM 和 32x32 乘法器执行指数运算 (a^b) 的模块上运行测试平台时 我在 FSM 输出 (update_counter,busy,update_prod) 的波形上遇到了一个奇怪的危险。

为什么会发生危险?

乘法器的模块已经过测试并且工作正常,危险与 FSM 密切相关 危害:

代码:

// Power Module
module power (
    input logic clk,              // Clock
    input logic reset,            // Reset
    input logic start,            // Start signal
    input logic[3:0] a,           // Input 
    input logic[2:0] b,           // Input 
    output logic busy,            // Power busy indication
    output logic[63:0] result     // Result
 );

// This module is calculating Result = a^b. 

// Local Variables. 
// Counter for Number of mult operations left. 
logic[4:0] counter;   
// Signals for mult.
logic mul_start, mul_busy, counter_clear, update_prod, clr_prod, counter_done, update_counter; 
// States for the FSM.
logic [1:0] cur_state, next_state;
// Inputs for the mult.
logic[31:0] b_input, a_input, product;
// Registers for the mult output.
logic[63:0]   mul_prod; 

// We want to assign the leg b of the mult 
// the input a as constant via b_input.
// Put your code here.
// ------------------
always_comb begin
    product=result;
    b_input=b;
    a_input=a;
end

// End of your code.

//Next, Declare the mult module we are going to use. 
// Put your code here.
// ------------------


mult32x32_fast mult(
    .busy(mul_busy),
    .product(mul_prod),
    .clk(clk),
    .reset(reset),
    .start(mul_start),
    .a(a_input),
    .b(product)
    );
    // End of your code.
    
    
    
// Initiating FFs Complete: 
always_ff @(posedge clk, posedge reset) begin
    if ( reset == 1'b1 ) begin
        cur_state<=2'b00;
    end
    else begin 
        cur_state<=next_state;
    end
    if (reset == 1'b1) begin
        counter <= 4'b00;
    end
    else begin 
        if (counter_clear == 1'b1) begin
            counter <= 4'b00;
        end
        else if ((counter < b_input - 1)&&update_counter==1'b1) begin
            counter <= counter + 1;
        end
    end
    if(reset==1'b1) begin
    result<=a_input;
    end
    else begin
        if(clr_prod==1'b1)begin
            result<=a;
        end
        else if(update_prod==1'b1)begin
            result<=mul_prod;
        end
        else begin
            result<=result;
        end
    end
end 
always_comb begin
    if (counter == b_input - 1) begin
        counter_done = 1'b1;
    end
    else begin
        counter_done = 1'b0;
    end

end

// Manage FSM Logic.
// We are going to use an FSM in order to manage 
// the multiplications. 
always_comb begin
    next_state=cur_state;
    mul_start=1'b0;
    counter_clear=1'b0;
    update_prod=1'b0;
    clr_prod=1'b0;
    busy=1'b0;
    update_counter=1'b0;
    case (cur_state) 
        2'b00: begin
            // Idle state - Waiting on 'start' signal.
            // Put your code here.
            // ------------------
            if(start==1'b0) begin
                next_state=2'b00;

            end
            else begin
                next_state=2'b01;
                clr_prod=1'b1;
                counter_clear=1'b1;
            end

            // End of your code.
        end
    
        2'b01: begin
            // Initiating state - Updating input for the mult 
            // and starting its operation.
            // Put your code here.
            // ------------------
            if(counter_done==1'b1)begin
                next_state=2'b00;
            end
            else begin
                next_state=2'b10;
                mul_start=1'b1;
                busy=1'b1;
            end
        
            // End of your code.
        end
        
        2'b10: begin
            // Waiting state - Waiting for the mult to finish 
            // How can you indicate?
            // Put your code here.
            // ------------------
            if(mul_busy==1'b1)begin
                next_state=2'b10;
                busy=1'b1;
            end
            else begin
                next_state=2'b01;
                update_prod=1'b1;
                update_counter=1'b1;
                busy=1'b1;
            end
        
            // End of your code.
        end            
    endcase
end
endmodule

测试台:

// testbench for the power module
module power_tb;

logic clk;            // Clock
logic reset;          // Reset
logic start;          // Start signal
logic [3:0] a;        // Input a
logic [2:0] b;        // Input b
logic busy;           // Multiplier busy indication
logic [63:0] result;  // Miltiplication product


/* Check the hardware you wrote with the two cases you chose.*/
// Put your code here
// ------------------
power uut(
.busy(busy),
.result(result),
.clk(clk),
.reset(reset),
.start(start),
.a(a),
.b(b)
);

initial begin
    clk=1'b1;
end
always begin
    #1 clk=~clk;
end

initial begin
    reset=1'b0;
    @(posedge clk);
    reset=1'b1;
    start=1'b0;
    a=0;
    b=0;
    repeat (4) begin
        @(posedge clk);
    end
    reset=1'b0;
    @(posedge clk);
    start=1'b1;
    a={1'b0,1'b0,1'b1,1'b0};
    b={1'b1,1'b1,1'b0};
    @(posedge clk);
    start=1'b0;
    @(negedge busy);
    @(posedge clk);
    start=1'b1;
    a={1'b1,1'b0,1'b1,1'b0};
    b={1'b0,1'b1,1'b1};
    @(posedge clk);
    start=1'b0;
    @(negedge busy);
end
// End of your code

endmodule

【问题讨论】:

  • 是的,这是一个零时间故障,顺便说一句,感谢您的帮助,我不认为我想要这些故障,尽管它们不会影响系统的逻辑,我认为它们不应该发生

标签: system-verilog fsm


【解决方案1】:

您需要在测试台中使用非阻塞分配,或者将输入从posedge clk 中更改出来。这将消除您的故障。

initial begin
    reset=1'b0;
    @(negedge clk); //move away from posedge
    reset=1'b1;
    start=1'b0;
    a=0;
    b=0;
    repeat (4) @(posedge clk);
    reset <=1'b0; // no longer a race
    @(posedge clk);
    start<=1'b1; 
    a<={1'b0,1'b0,1'b1,1'b0};
    b<={1'b1,1'b1,1'b0};
    ...

【讨论】:

  • 你能更详细地解释一下“改变你的输入远离 posedge clk”部分吗?我想我没明白你的意思。
  • 如果您注意到危险仅在 fsm 开始运行时的分配之后发生,所以我不知道这是否是导致危险的主要问题,您还可以看到我正在等待更改每个输入所以没有真正的比赛。所以我不能 100% 确定可以解决问题
  • 你没有显示mult32x32_fast ,所以我不知道这可能是如何导致故障的。
  • 嗯,你是对的,但 mult32x32 不依赖于其他部分,如果你注意到故障只发生在 FSM 输出上,那么我认为它可能必须与开关盒有关,但我不知道在哪个部分。
  • 故障只能来自未使用非阻塞分配分配的 FSM always_comb 块输入。这可能是来自测试平台的startcounter_done,或者来自mult32x32_fastmul_busy
猜你喜欢
  • 1970-01-01
  • 2016-07-22
  • 1970-01-01
  • 2019-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-20
  • 2018-04-08
相关资源
最近更新 更多