How to write a verilog code in two-always-block style with multiple state regs? -


i'm begginer of verilog. read several materials recommended verilog coding styles this paper , stackoverflow's questions.
now, learned them "two block style" recommended; separate code 2 parts, 1 combinational block modifies next, , sequential block assigns state reg this.

reg [1:0] state, next;  @(posedge clk or negedge rst_n)     if (!rst_n)         state <= idle;     else         state <= next;   @(state or go or ws) begin      next = 'bx;      rd = 1'b0;      ds = 1'b0;     case (state)         idle : if (go) next = read;                else next = idle;  ... 

and here question. example codes found have 1 pair of registers named state , next.
however, if there multiple regs preserve kinds of state, how should write codes in state-and-next style?
preparing next regs corresponding each of them looks little redundant because regs doubled.

for instance, please @ uart sender code of rs232c wrote below. needed wait_count, state , send_buf state regs. so, wrote corresponding wait_count_next, state_next , send_buf_next next combinational block. looks bit redundant , troublesome me. there other proper way?

module uart_sender #(     parameter clock = 50_000_000,     parameter baudrate = 9600 ) (     input clk,     input go,     input [7:0] data,     output tx,     output ready );  parameter wait_time = clock / baudrate;  parameter send_ready = 10'b0000000000,         send_start = 10'b0000000001,         send_stop  = 10'b1000000000;  reg [31:0] wait_count = wait_time,         wait_count_next = wait_time; reg [9:0] state = send_ready,         state_next  = send_ready; reg [8:0] send_buf = 9'b111111111,         send_buf_next = 9'b111111111;  @(posedge clk) begin     state <= state_next;     wait_count <= wait_count_next;     send_buf <= send_buf_next; end  @(*) begin     state_next = state;     wait_count_next = wait_count;     send_buf_next = send_buf;     case (state)         send_ready: begin             if (go == 1) begin                 state_next = send_start;                 wait_count_next = wait_time;                 send_buf_next = {data, 1'b0};             end         end         default: begin             if (wait_count == 0) begin                 if (state == send_stop)                     state_next = send_ready;                 else                     state_next = {state[8:0], 1'b0};                 wait_count_next = wait_time;                 send_buf_next = {1'b1, send_buf[8:1]};             end             else begin                 wait_count_next = wait_count - 1;             end         end     endcase end  assign tx = send_buf[0]; assign ready = state == send_ready;  endmodule 

i think did job , correctly flopped variables. issue without flops have loop. i.e. if write following, simulation loop , silicon burn out:

 always_comb wait_count = wait_count - 1; 

so, need stage inserting flop:

 always_ff @(posedge clk)     wait_count <= wait_count - 1; 

or in case you used intermediate wait_count_next style:

 always_ff @(posedge clk)     wait_count_next <= wait_count;  always_comb     wait_count = wait_count_next; 

you might or might not have issue last assignments. version of signals want assign tx , ready? flopped 1 or not?

and yes, can split theses blocks in multiple blocks, in case there seems no need.

and yes, other style write in single flop block. reduce readability, more prone errors , might have synthesis issues.


Comments

Popular posts from this blog

python - Selenium remoteWebDriver (& SauceLabs) Firefox moseMoveTo action exception -

html - How to custom Bootstrap grid height? -

transpose - Maple isnt executing function but prints function term -