Danp
Danp

Reputation: 1

regarding always block in implementing ARM cpu in verilog

I'm trying to implement the register file in an ARM CPU in verilog. I'm very new to verilog so I had trouble.

I want to make the register file save in it's 15th register the value PC+8 and in register number 0 the value 0 in the beginning, so that the register file is able to give PC+8 as output when it's input for one of the read-register is 15 and so on.

Currently, I've written the code like this

reg[31:0] register[15:0];   

initial 
begin
    register[15] = register15;//register15 is the input holding PC+8 as it's value
    register[0] = 32'h00000000;
end
always @(posedge clk)
begin
    outreg1 <= register[A1];// outreg1,2 are outputs (values of register A1, A2)
    outreg2 <= register[A2];
end

However, I want to make it all happen in posedge of clk, when 'register-read' happens. But if I do that, would I have to make all the statements in always @(posedge clk) a blocking assignment '='to make it go in order and assign 15 and 0 first?

My understanding of blocking and unblocking assignments aren't very clear so I am not sure if that would work or not.

Upvotes: 0

Views: 203

Answers (1)

Serge
Serge

Reputation: 12354

So, this looks like an attempt to remap of input values 'register0, ... register15' to a set of 'outreg1...' using 'A1...' as map manipulators.

In this case you cannot use initial block. Initial block runs only once in the simulation at its beginning and cannot react to the input changes. They are not synthesizable as well. Since you said that 'registerN' are also inputs, you'd better create 2 different always_blocks;

reg[31:0] register[15:0];   

always @* 
begin
    register[15] = register15;//register15 is the input holding PC+8 as it's value
    register[0] = 32'h00000000;
end

always @(posedge clk)
begin
    outreg1 <= register[A1];// outreg1,2 are outputs (values of register A1, A2)
    outreg2 <= register[A2];
end

difference between blocking and non-blocking assignments is that with non-blocking assignments the real value will be assigned to the variables later, after all evaluation of the posedge is done for all such blocks in the design. This allows simulation to behave more like hardware in respect to flops and latches. i.e. if you have one flop A feeding another flop B at the same 'posedge clk', the flop B will catch the output of A as it existed before the posedge. This is the way the hardware behaves. With blocking assignments the result of the simulation will be unpredictable in such a case, depending on simulator implementation.

So, the rule of thumb is to use non-blocking assignment for all 'outputs' of the always blocks representing latches and flops. Everything else must be blocking. It means that flop/latch blocks can use blocking for intermediate variables if needed, but it is better to be avoided.

Upvotes: 2

Related Questions