Skip navigation.
Home

Verilog Inferred RAM

When doing an FPGA design, it is sometimes useful to write some HDL code to infer a block RAM element. Most synthesizers will support this construct. The following snippet demonstrates how to infer a block ram in Verilog.

module verilog_ram_infr #(parameter ADDR_WIDTH=8, DATA_WIDTH=8, DEPTH=256)
(
 input                   clk,       // clock signal.
 input  [ADDR_WIDTH-1:0] addr,      // address signal.
 input                   we,        // write enable signal.
 input  [DATA_WIDTH-1:0] data_in,   // data input.

Verilog Concatenation

Concatenation is a useful feature in Verilog. It allows multiple signals to be combined into one signal. Concatenation in Verilog is achieved by using the curly braces with the signals to be concatenated separated by commas inside as demonstrated in the following snippet.

module verilog_concat;
 
reg [7:0] register_a;
reg [3:0] register_b;
reg [3:0] register_c;
reg [2:0] register_d;
 
initial begin
  register_b = 4'hA;
  register_c = 4'hF;
  register_d = 3'h7;
 
  // concat register b and register c into register a
  register_a = {register_b,register_c};

Verilog Display with No Newline ($write statment)

Sometimes it is desired to output some text to the standard output without displaying a newline character. The Verilog command $display() will display text in a printf fashion, but it always comes with a newline. Conversely, the $write() command behaves just as the $display() command but does not include the new line. The following example uses the $write() command to display a table of the numbers 0-99.

module no_newline;
 
integer ii,jj;
 
initial begin
  for(ii=0;ii<10;ii=ii+1) begin
    for(jj=0;jj<10;jj=jj+1) begin
      $write("%d ",jj+ii*10);
    end

Verilog Dual Edge Detector

It is often necessary to detect when a particular signal is transitioning from high to low or low to high. It is also sometimes useful to get a pulse that is a single clock cycle wide to trigger other logic in the system. This snippet demonstrates how a single cycle wide pulse can be generated on the falling edge of a signal or the rising edge of a signal.

module dual_edge_detect
(
 input  clk,
 input  signal,
 output pulse
);
 
reg     signal_prev;
 
always @(posedge clk) signal_prev <= signal;

Verilog Falling Edge Detector

It is often necessary to detect when a particular signal is transitioning from high to low. It is also sometimes useful to get a pulse that is a single clock cycle wide to trigger other logic in the system. This snippet demonstrates how a single cycle wide pulse can be generated on the falling edge of a signal.

module falling_edge_detect
(
 input  clk,
 input  signal,
 output pulse
);
 
reg     signal_prev;
 
always @(posedge clk) signal_prev <= signal;
 
assign pulse = ~signal & signal_prev;
 
endmodule

Verilog Rising Edge Detector

It is often necessary to detect when a particular signal is transitioning from low to high. It is also sometimes useful to get a pulse that is a single clock cycle wide to trigger other logic in the system. This snippet demonstrates how a single cycle wide pulse can be generated on the rising edge of a signal.

module rising_edge_detect
(
 input  clk,
 input  signal,
 output pulse
);
 
reg     signal_prev;
 
always @(posedge clk) signal_prev <= signal;
 
assign pulse = signal & ~signal_prev;
 
endmodule

SystemVerilog Multiplexor

A multiplexor written in SystemVerilog can take advantage of a few of SystemVerilog's keywords. For instance, the always_comb block is used to indicate combinational logic and the unique case statement makes it clear to the sythesizer and simulator that only one branch in the case statement should ever be taken. Also check out the Verilog implementation of the multiplexor.

module mux4_2
(
 input  logic       a,b,c,d,
 input  logic [1:0] sel,
 output logic       z
);
 
always_comb begin
  unique case (sel)

Verilog JK Flip Flop

A JK flip flop can be considered the "universal" flip flop since any other flip flop can be constructed from it. While this is an interesting point, it does not have any real world implications since digital electronics is dominated by the D flip flop. Nevertheless, it makes for an interesting discussion.

Here is a snippet for the JK flip flop.

module jk_flip_flop (
input      clk,
input      j,                     
input      k,
output reg q
                     );
 
always @(posedge clk)
  case ({j,k})
    2'b11 : q <= ~q;    // toggle.

SystemVerilog always_comb

The always_comb block in SystemVerilog provides a means to prevent simulation and synthesis mismatches. The idea is that both the simulator and synthesizer will be able to analyze this block and determine if it properly infers combinational logic. If it does not, an error can be thrown. This snippet demonstrates the most basic usage of this type of block and it also demonstrates the usage of the unique keyword. This keyword ensure that only one branch of the case statement is active at any time.

module systemverilog_always_comb
(
  input  logic [3:0] data_input,

SystemVerilog always_ff

The always_ff block in SystemVerilog provides a means to prevent simulation and synthesis mismatches. The idea is that both the simulator and synthesizer will be able to analyze this block and determine if it properly infers sequential logic. If it does not, an error can be thrown. This snippet demonstrates the most basic usage of this type of block.

module systemverilog_always_ff 
(
  input  logic clk,
  input  logic d,
  output logic q
);
 
always_ff @(posedge clk)         // always_ff
  begin : sysverilog_always_ff   // optional label.
    q <= d;

Syndicate content