I have designed a register bank (pipeline register) to be used in a pipeline-architecture. The code of the register is:

module if_id(   input clk,
                input [31:0] newPC, 
                input [31:0] instr, 

                output reg [31:0] newPCout, 
                output reg [31:0] instrOut);

    reg [63:0] temp;
    always @ (posedge clk) begin
        temp <= {newPC,instr};
    always @ (negedge clk) begin
        newPCout <=  temp[63:32];
        instrOut <= temp[31:0];

GTKwave Graphs for inputs and outputs of the given module

Now in this waveform, instrOut changes every 2nd clock cycle. Why? I cannot seem to find the fault in the code, according to me the output should change at every negedge of the clock.

This is the image of the test bench, pipe1 is the instance of if_id module.

module tb(); // tb for fetch
    reg [31:0] baddress;
    reg clk;
    reg pcsource;

    wire [31:0]newpc;
    wire [31:0]instr;

    wire [31:0]newpcpipe1;
    wire [31:0]instrpipe1;

    wire [31:0]rd1,rd2;
    wire [31:0]imm;
    wire [4:0]rs,rt,rd;
    wire [5:0]opcode;

    //main Control
    wire [3:0]ex;
    wire [2:0]mem;
    wire [1:0]wb;

    wire [3:0] exo;
    wire [1:0]wbo;
    wire [2:0]memo;
    wire [31:0] rd1o;
    wire [31:0] rd2o;
    wire [31:0] immo;
    wire [4:0]  rso;
    wire [4:0]  rto;
    wire [4:0]  rdo;
    wire [31:0] newPCo;

    wire [31:0]tPc;
    wire[31:0] AluRes;
    wire [4:0] regDstAdd;
    wire zero;

    wire [1:0]wb_m;
    wire [2:0]mem_m;
    wire zero_m;
    wire [31:0] AluOut_m;
    wire [4:0] regdst_m;
    wire [31:0] newPC_m;

    wire PCSrc;
    wire [31:0] aluouto;

    wire regWrite;
    wire [31:0] AluOut_w;
    wire [4:0] regdst_w;

    fetch fetch1(clk,pcsource,baddress,newpc,instr);
    if_id pipe1(clk,newpc,instr,newpcpipe1,instrpipe1);

    decode decode1(clk,instrpipe1,AluOut_w,regdst_w,regWrite,rd1,rd2,imm,rs,rt,rd,opcode);
    MainControl mc1(opcode,ex,mem,wb);
    id_ex pipe2(clk,wb,mem,ex,newpcpipe1,rd1,rd2,imm,rs,rt,rd,exo,wbo,memo,rd1o,rd2o,immo,rso,rto,rdo,newPCo );

    ex ex1(newPCo,rd1o,rd2o,immo,rto,rdo,exo,tPc,AluRes,regDstAdd,zero);
    ex_mem pipe3(clk,wbo,memo,tPc,AluRes,zero,regDstAdd,wb_m,mem_m,zero_m,AluOut_m,regdst_m,newPC_m);

    mem mem1(mem_m,AluOut_m,zero_m,PCSrc,aluouto);
    mem_wb pipe4(clk,wb_m,AluOut_m,regdst_m,regWrite,AluOut_w,regdst_w);

    initial begin

    initial begin
        clk = 1'b0;
        forever #5 clk = ~clk;
    initial begin
        //$monitor($time," clk = %b \n ,instr=%b, newPC = %b,",clk,instrpipe1,newpcpipe1);
        #10 baddress = 32'b0; pcsource = 0;
        #200 $finish;
  • 1
    \$\begingroup\$ It's obvious that temp is only changing on every other clock, which is weird. Show us the code for your testbench. \$\endgroup\$
    – Dave Tweed
    Commented Mar 30, 2020 at 10:28
  • \$\begingroup\$ Test Bench This is the image of the test bench, pipe1 is the instance of if_id module. \$\endgroup\$ Commented Mar 31, 2020 at 4:27
  • 2
    \$\begingroup\$ Not as an image! Paste the actual code into your question. \$\endgroup\$
    – Dave Tweed
    Commented Mar 31, 2020 at 11:14

1 Answer 1


Looking at the waveform your instr is weird/wrong.

It is picked-up in tmp at the same clock edge that it changes. This is indicative that instr change at or before the clock edge. Not after.

Did you use this in your test-bench/code?

always @ (posedge clk)
   instr = some_test_value;

instead of?

always @ (posedge clk)
   instr <= some_test_value;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.