2
votes

I'm a bit of a neophyte with Verilog, and I have just started working on a project, and I'm trying to verify that the code I have started with is workable. The code snippet below is unloading a FIFO into a vector of 8 bit registers. At each clock cycle it unloads a byte from the FIFO and puts it in the end of the register chain, shifting all the other bytes down the chain.

reg   [ 7:0]            mac_rx_regs [0 : 1361];
 generate for (ii=0; ii<1361; ii=ii+1)
  begin: mac_rx_regs_inst            
    always @(posedge rx_clk_int, posedge tx_reset)  
    if (tx_reset) begin
      mac_rx_regs[ii]   <= 8'b0;
      mac_rx_regs[1361]  <= 8'b0;
    end else begin
      if (rx_data_valid_r) begin
        mac_rx_regs[ii]   <= mac_rx_regs[ii+1];
        mac_rx_regs[1361]  <= rx_data_r;
      end
    end
  end
  endgenerate

I'd like to know if this is a good way to do this. I would have expected to just address the register vector with the byte count from reading the FIFO. I'm concerned that this isn't deterministic in that the order that the generated always blocks run is not specified, plus it seems that it'll cause a lot of unnecessary logic to be created for moving data from one register to another.

1

1 Answers

2
votes

To start with, you don't really need to worry about the number of always statements in general. If they are all using the same clock and reset, you will get expected behavior relative to interaction between the processes. The one thing I do, that is more about style than anything else, is to add a #FD to my flop assignments like shown below to make simulation look a little better, IMHO.

Also, this is simple enough that you could code this as a single process.

parameter FD = 1;
reg [1361*8-1:0] mac_rx_regs;  // Arrays are good if you are trying to 
                               // infer memory, but if you are okay 
                               // with registers, just declare a vector.
always @ (posedge clk or posedge reset)
begin 
   if (reset)
      mac_rx_regs <= #FD 1361*8'h0;
   else
      // This next statement shifts in a new 8 bits when rx_data_valid_r is asserted.
      // It will assign max_rx_regs to max_rx_regs (nop) when deasserted.
      mac_rx_regs <= #FD rx_data_valid_r ? {mac_rx_regs[1361*8-9:0],rx_data_r} : 
                                            mac_rx_regs;
end