First of all, don't forget about begin - end around sections of code:
else begin r_reg[0]=data; r_reg = r_reg<<1; end
Without this, only r_reg[0]=data will be in the else clause of the if . This will work, but is considered bad style due to blocking statements in a consistent logical description ...
Secondly, to simulate sequential blocks, use non-blocking assignments ( <= ), or your calculations may fail (google non-blocking and blocking for more information). Your example may work very well (did you try it in the simulator?), But if the situation gets complicated and more variables are added, everything may break.
always @(posedge clk or negedge reset) begin if(!reset) r_reg <= 0; else begin // This is horrible! Don't write code like this! r_reg[0] = data; // blocking r_reg <= r_reg<<1; // non-blocking end end
For this reason, it is sometimes recommended that combined logic be separated from sequential logic so that you can write non-blocking assignments to registers in sequential blocks and block in combined blocks and never worry about scheduling.
To program this way, you need to calculate which next output should use the current state, and therefore the r_next bus in the response. I think this also helps the synthesis tool if all the triggers are separated from the surrounding combo logic in this way.
Also, if your reset is active low (i.e., LOW resets), it should be named as such, e.g. resetb or reset_n .
Marty source share