0
\$\begingroup\$

So this is my current code.

  module top
  (input clk,
   input reset,
   input write,
   input [4:0] wrAddr,
   input [31:0] wrData,
   input [4:0] rdAddrA,
   output [31:0] rdDataA,
   input [4:0] rdAddrB,
   output [31:0] rdDataB);

   reg [31:0]    regfile [0:31];

   assign rdDataA = regfile[rdAddrA];
   assign rdDataB = regfile[rdAddrB];

   integer   i;

   always @(posedge clk) begin
      if (reset) begin
            for (i = 0; i < 8; i = i + 1) begin
                regfile[i] <= 0;
            end
      end else begin
            if (write) regfile[wrAddr] <= wrData;
      end // else: !if(reset)
   end

    endmodule

It works fine, but it reads immediately. I want to set this up so it reads only on the falling edge of the clock cycle. I'm not sure how to add posedge and negedge blocks without running into issues with constant drivers. Any tips on the proper way to do this would be great. Thanks.

\$\endgroup\$
2
\$\begingroup\$

Reading from a register is inherently asynchronous. I think what you really want is for rdDataA and rdDataB to be updated only at a falling clock edge. To accomplish this, just put their assignments inside an always @(negedge clk) block and use non-blocking assignments instead of the concurrent assign statement.

always @(negedge clk) begin
    rdDataA <= regfile[rdAddrA];
    rdDataB <= regfile[rdAddrB];
end
\$\endgroup\$
  • \$\begingroup\$ Don't forget to change output [31:0] to output reg [31:0] otherwise it would be considered net types which cannot be assigned in an always block. \$\endgroup\$ – Greg Oct 11 at 19:48
  • \$\begingroup\$ Thank you, this works perfectly. \$\endgroup\$ – gbf Oct 11 at 21:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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