2014-06-07 4 views
0

순차 추가/시프트 승수에 대한 내 Verilog 코드입니다. "XXXXXXX"를 출력으로받습니다. 재설정을 높게 설정하면 모든 0이 출력으로 수신됩니다. 누군가 내가 내가 뭘 잘못하고 있는지 확인하는데 도움을 줄 수 있습니까?Verilog 코드, 추가 및 시프트를 사용하는 순차 승수

팁/힌트를 보내 주셔서 감사합니다.

module MULTIPLY_revision (
    input    clk, reset, start, 
    input  [7:0] A_in, B_in, 
    output reg   done_tick, 
    output wire [15:0] product 
); 

localparam [1:0] 
    idle = 2'b00, 
    op = 2'b01, 
    shift = 2'b10; 

// signal declaration 
reg  carry, next_carry; 
reg [1:0] state, next_state; 
reg [7:0] reg_PL, PL, reg_PH, PH, reg_a_multiplicand, a_multiplicand; 
reg [4:0] counter, next_counter; 

assign product = {reg_PH, reg_PL}; 

always @(posedge clk, posedge reset) 
    if (reset) begin 
    state    <= idle; 
    counter   <= 0; 
    carry    <= 0; 
    reg_PL    <= 0; 
    reg_PH    <= 0; 
    reg_a_multiplicand <= 0; 
    end 
    else begin 
    state    <= next_state; 
    carry    <= next_carry; 
    counter   <= next_counter; 
    reg_PL    <= PL; 
    reg_PH    <= PH; 
    reg_a_multiplicand <= a_multiplicand; 
    end 

// next state logic 
always @ * begin 
    done_tick  = 1'b0; 
    PL    = reg_PL; 
    PH    = reg_PH; 
    a_multiplicand = reg_a_multiplicand; 
    next_carry  = carry; 
    next_counter = counter; 
    next_state  = state; 

    case(state) 
    idle: begin 
     if(start) begin 
     next_counter = 7; // load 7 for 8 bits down counter 
     PL    = B_in; // load multiplier into lower half 
     PH    = 8'b0; // clear upper half. 
     a_multiplicand = A_in; // load A multiplicand into register. 
     next_state  = op; 
     end 
    end 

    op: begin 
     if(reg_PL[0] == 1) begin 
     {next_carry,PH} = reg_PH + reg_a_multiplicand;  // add A multiplicand to upper half with carry bit. 
     end 
     next_counter = counter - 1; 
     next_state = shift;    
    end 

    shift: begin 
     {next_carry,PH,PL} = {carry,reg_PH,reg_PL} >> 1; // putting everything back together and shifting everything to the right once. 
     if(next_counter == 0) begin 
     next_state = idle; 
     end 
     else begin 
     next_state = op; 
     end 
    end 

    default: begin 
     next_state = idle; 
    end 
    endcase 
end 


endmodule 


    `timescale 1ns/1ps 

내 테스트 벤치는 다음과 같습니다. 더 나은 방법을 작성하는 방법에 대한 정보도 좋습니다.

module mytest; 

// Inputs 
reg clk; 
reg reset; 
reg start; 
reg [7:0] A_in; 
reg [7:0] B_in; 

// Outputs 
wire done_tick; 
wire [15:0] product; 

// Instantiate the Unit Under Test (UUT) 
MULTIPLY_revision uut (
    .clk(clk), 
    .reset(reset), 
    .start(start), 
    .A_in(A_in), 
    .B_in(B_in), 
    .done_tick(done_tick), 
    .product(product) 
); 


initial begin 
    // Initialize Inputs 
    clk = 0; 
    reset = 0; 
    start = 0; 
    A_in = 0; 
    B_in = 0; 

    // Wait 100 ns for global reset to finish 
    #100; 

      clk = 1; 
    reset = 0; 
    start = 1; 
    A_in = 4; 
    B_in = 4; 

    #100 

    clk = 1; 
    reset = 0; 
    start = 1; 
    A_in = 5; 
    B_in = 6; 

    end 

always 
#20 clk = !clk; 


endmodule 
+0

테스트 벤치를 게시하고 싶을 수 있습니다. 입력을 정확하게 조절하는 경우 출력물에 X 표시가 없어야합니다. – Ciano

+0

또한 리셋을 해제하고 시작을 선언하고 A_in 및 B_in 신호가 0이 아닌 경우 몇 클록 사이클 후에 출력이 0이 아닙니다. – Ciano

+0

정말 고마워요, 그건 내 테스트 벤치 였고, 정확하게 시계를 맞추지 못했습니다. – user3533556

답변

0

Ciano는 지적했듯이 시계를 올바르게 시작할 수 없습니다. 또한 결핵에서 리셋을 주장하지 마십시오.

initial clk = 0; 
always clk = #20 ~clk; 

initial 
    begin 
    reset = 1; 
    // set all inputs to quiescent 
    #100; 
    reset = 0; 
    // continue stimulus 
    end 
0

다음은 모듈을 테스트하는 데 도움이됩니다. 하지만 그것은 당신의 모듈 doesnt 일처럼 보인다.

initial begin 
    // Initialize Inputs 
    clk = 0; 
    reset = 0; 
    start = 0; 
    A_in = 0; 
    B_in = 0; 

    @(posedge clk); 
    reset = 1; 
    repeat(2)@(posedge clk); 
    reset = 0; 
    @(posedge clk); 
    start = 1 ; 
    A_in = 5; 
    B_in = 6; 
    wait(done_tick == 1); 
    $display("A_In = %d B_In = %d Product = %d",A_in,B_in,product); 





    end 

always 
#20 clk = !clk;