Skip to content

Verilog SystemVerilog

Alexis edited this page Feb 20, 2024 · 43 revisions

Timing constraints

{"reg":[
  {"bits": 8, "name": "things"},
  {"bits": 2, "name": "stuff" },
  {"bits": 6},
 ],
 "config": { "bits":64,"lanes":1 }
 }

Do/Tcl file

# Add every signal starting with <status> recursively
add wave -noupdate -group {ddr4status} -r -radix hexadecimal {/status*}
# Add every signal containing <status> recursively
add wave -noupdate -group {ddr4statusstar} -r -radix hexadecimal {/*status*}

Edge detector:

module pos_edge_det ( input sig,
                      input clk,
                      output pe);
 
  reg   sig_dly;
 
  always @ (posedge clk) begin
    sig_dly <= sig;
  end
 
  assign pe = sig & ~sig_dly; // for posedge
  assign ne = ~sig & sig_dly; // for negedge
  assign npe = sig ^ sig_dly;  // for both pos and neg edges
endmodule 


logic rx_valid_real;
logic [9:0] rx_valid_latency;
always_ff @(posedge clk)
  rx_valid_latency <= (rst|rx_ack)? '0: {rx_valid_latency[8:0], rx_valid};
assign rx_valid_real = rx_valid_latency[1];

CDC: Clock domain crossing

Floating point addition

Simulation modelsim questa:

To start Modelsim without globbing a simulator license, you need to start it with vsim -lic_no_lnl option

Most of the time you are looking at waveforms. use the waveform license to do this, and run your actual simulations in batch mode. If you simulate from graphics mode, you hold the simulation license the entire time you have modelsim open.

Simulation

  • To disaply the system/host date and time: $system("date");

PRBS LFSR Random numbers generator

reg [31:0] d;
always @(posedge clk) begin
    d <= (rst)? 'd1: { d[30:0], d[31] ^ d[21] ^ d[1] ^ d[0] };
end

OR 
logic [3:0][21:0] randomaddr;
logic [3:0][63:0] randomdata;

for (h=0;h<=3;h=h+1) begin
  always @(posedge mem_if.K) begin
      randomaddr[h] <= { randomaddr[h][20:0], randomaddr[h][21] ^ randomaddr[h][20] };
      randomdata[h] <= {randomdata[h][62:0], randomdata[h][63] ^ randomdata[h][62] ^ randomdata[h][60] ^ randomdata[h][59]};
  end
end

initial begin
  ref_clk         <= 0;
  reset           <= 1;
  randomaddr[3]       <= 1;
  randomaddr[2]       <= 20;
  randomaddr[1]       <= 50;
  randomaddr[0]       <= 100;

  randomdata[3]       <= 1;
  randomdata[2]       <= 20;
  randomdata[1]       <= 50;
  randomdata[0]       <= 100;
end

Parameterize parameters:

localparam CLKFBOUT_MULT_F = returnCLKFBOUT_MULT_F(FREQ);
function shortreal returnCLKFBOUT_MULT_F(int F);
  if (F == 550) begin
    return 11.000;
  end else begin
    return 10.000;
  end
endfunction
localparam KEEP_VERILOG="true";
(*keep=KEEP_VERILOG*) reg mysig;

OR using generate block:

if (KEEP_VERILOG) begin : blockname
  (*keep="true"*)reg mysig;
end else begin : blockname
  reg mysig;
end
// do something with blockname.mysig

Case range

  • using inside keyword
case(subcnt) inside
  0:begin
    if (dataout.data=="A")
      states_parser  <= PRSR_MAC;
  end
  [3:19]:begin
  end
endcase

Example for ASCII waveforms

──┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐
  └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─  fast_clk
────────┬───┬───┬───────────────────
XXXXXXXX|D1 |D2 |XXXXXXXXXXXXXXXXXXX  fast_data_in 16b
────────┴───┴───┴───────────────────
        ┌───────────────────────────
────────┘                             mux_reset
────────┬───┬───┬───┬───┬───┬───┬───
XXXXXXXX| 0 | 1 | 0 | 1 | 0 | 1 |XXX  mux
────────┴───┴───┴───┴───┴───┴───┴───
────────┬───┬───┬───────────────────
XXXXXXXX|XX |D2 |XXXXXXXXXXXXXXXXXXX  data[1]
XXXXXXXX|D1 |D1 |XXXXXXXXXXXXXXXXXXX  data[0]
────────┴───┴───┴───────────────────
┌───┐   ┌───┐   ┌───┐   ┌───┐   ┌───
┘   └───┘   └───┘   └───┘   └───┘     slow_clk
────────────────┬───────┬───────────
XXXXXXXXXXXXXXXX| D2-D1 |XXXXXXXXXXX  slow_data_out 32b
────────────────┴───────┴───────────

xpm_fifo_axis PACKET_MODE="true"

It doesn't work in simulation, you need to keep the reset asserted for more than 100ns...