Russell
Russell

Reputation: 3457

Converting from VHDL to Verilog, specific cases

I am used to programming in VHDL and I want to know the "best" way to do some types of actions that I use in VHDL in Verilog. I suppose that each of these could be their own dedicated question, but I thought it would be nice to have a collection of these for people just to see a bunch of Verilog examples in one place rather than spread across 5 questions. Thanks.

Here are some examples that I would like to see best practices for:

Replacement for Others:

I know that for signal assignments in Verilog, you can do:

data <= 'b0;

This assigns all bits in data to zero, and if data changes its width it still works. Neat trick, but what about when instantiating a module and tying an input to zero? E.G.

   Data_Module UUT
      (
       .Data(8'h00),  //'b0 doesn't work here

Replacement for Attributes:

Writing flexible code is nice, so I like to define my port widths based on generics such that if the port widths change all it takes is a quick update of the generic and everything still works. I often have VHDL code like this:

signal some_data : std_logic_vector(g_DATA_WIDTH+g_GENERIC-1 downto 0);
signal some2     : std_logic_vector(some_data'length-1 downto 0);

-- OR I may have this:
left_bit <= some_data'left;

Long when/else chain:

This one gives me troubles. Is the best way to do this to set up a combinational always block and use a case-statement on index? That seems like a lot of code. Using the ? operator can lead to some illegible code, so I prefer not to do that for long when/else chains.

some_data <= X"01" when index = 0 else
             X"04" when index = 1 else
             X"02" when index = 2 else
             X"F0";

Assertions:

How can I trigger a modelsim assertion in Verilog? I often use these on my VHDL FIFOs to check for overflow/underflow conditions. E.G.

assert NOT_FIFO_OVERFLOW report "FIFO has overflowed, that's a bad thing" severity failure;

Generate Blocks:

In VHDL, it's nice to be able to generate a block of code based on a generic, or completely remove it if that generic is not present. E.G.

  g_LFSR_3 : if g_Num_Bits = 3 generate
    w_XNOR <= r_LFSR(3) xnor r_LFSR(2);
  end generate g_LFSR_3;

  g_LFSR_4 : if g_Num_Bits = 4 generate
    w_XNOR <= r_LFSR(4) xnor r_LFSR(3);
  end generate g_LFSR_4;

State Machine Enumeration:

In Verilog, do I really need to create parameters for each individual state? If that's the best way to do it, I'll do it, but it seems like a lot. I like that in VHDL you can create a type that just contains each state and then create a state machine signal of that type.

Creating Integers:

Often I have code like this:

signal Row_Count : integer range 0 to c_TOTAL_ROWS-1 := 0;

What's the best way to do this in Verilog? Do I need to take the log base 2 of c_TOTAL_ROWS to find the max width of it then define a reg based on this? That seems like a lot of work. I believe that Verilog creates 32-bit integers by default, but I do not want to generate extra logic if I do not need to. Also I like that if I exceed the expected range, my Modelsim simulation will crash.

Upvotes: 4

Views: 3846

Answers (1)

Greg
Greg

Reputation: 19094

Not everything can be directly translated into Verilog.

Replacement for Others:

Verilog

'b0 should work with port declinations. There should be compiling warnings, not errors. Some simulator try to be backward compatible to IEEE Std 1364-2005 where 'b0 is an inferred 32'b0. According to IEEE Std 1364-2005 &sect 3.5.1 this 32-bit max limitation seems to be removed. Simulators may be lagging behind the standard. It is a simulator limitation if the module port instantiation .Data('b0), results in a compiling error.

SystemVerilog

SystemVerilog added a fill constants '0, '1, 'x, & 'z. '0, 'x, & 'z are the same as IEEE Std 1364-2005 'b0, 'bx, & 'bz with one less character. 'b1 is {(N-1){1'b0},1'b1} where '1 is {N{1'b1}} with N being the width of the destination vector/packed-array.

Replacement for Attributes:

Verilog

Non that could be found.

SystemVerilog

logic [g_DATA_WIDTH+g_GENERIC-1:0] some_data;
logic [$size(some_data)-1:0] some2;
logic [$bits(some_data)-1:0] some3; // or with $bits for vector

// OR I may have this:
left_bit <= some_data[$left(ome_data)];

Long when/else chain:

Verilog/SystemVerilog (Same for both)

some_data <= (index == 0) ? 'h01 :
             (index == 1) ? 'h04 :
             (index == 2) ? 'h02 :
                            'hF0 ;

The works functionally but may not give the best timing and area when synthesized. When some synthesizers see ?: they will always generate a 2-to-1 mux; if they see a chain of nested ?: it will create a chain of 2-to-1 muxes even is a 4-to-1 mux (or other mux types) is available.

It a little more typing but this should give a better result (same functionality)

case(index)
  0 : some_data <= 'h01;
  1 : some_data <= 'h04;
  2 : some_data <= 'h02;
  default : some_data <= 'hF0;
endcase

Assertions:

Verilog

Verilog does not have assertions built into the language. Creating some for of checkers are not to challenging (for example non-overlaping concurrent check can be done with a always block), but flagging the error to the simulator may be a bit tricky. Usually a global error counter incremented of failures and the simulation will abort with $finish if a user defined error limit is reached. There might be a PLI/VPI solution or a something that simulator specific.

SystemVerilog

SystemVerilog has two main types of assertions; concurrent and immediate. Immediate exist inside of a procedural block (i.e. begin-end) such as:

optional_label : assert (NOT_FIFO_OVERFLOW) $error("FIFO has overflowed, that's a bad thing");

Concurrent assertions run in the module scope, out side of a procedural block. They use a clocking reference.

optional_label : assert property (@(posedge clk) !$stable(fifo_ptr) |->  fifo_pt < FIFO_DEPTH) $error("FIFO has overflowed, that's a bad thing");

Refer to IEEE Std 1800-2012 § 16. Assertions for further explinations and examples.

Note - if using UVM, use `uvm_error instead of $error

Generate Blocks:

Verilog/SystemVerilog

Generate blocks were added in Verilog's IEEE Std 1364-2001. The generate-endgenerate are actually optional, but make a good visual reference. See IEEE Std 1800-2012 § 27. Generate constructs for full detail

generate
  if (g_Num_Bits = 3) begin : g_LFSR_3
    xnor (w_XNOR, r_LFSR[3], r_LFSR[2]);
  end : g_LFSR_3
  if (g_Num_Bits = 4) begin : g_LFSR_4
    always @* begin
      w_XNOR = ~{r_LFSR[4] ^ r_LFSR[3]};
    end
  end
endgenerate

Note: In this particular example part-select addressing would also work in Verilog/System Verilog: w_XNOR = ~^r_LFSR[g_Num_Bits-:2]; IEEE Std 1800-2012 § 11.5.1

State Machine Enumeration:

Verilog

Got to use parameter here if it is desired to using names instead of memorizing indexes. It legal possible to define multiple parameter in a one statement, but identifier still needs to define its value.

SystemVerilog

Enumeration is supported. See IEEE Std 1800-2012 § 6.19 Enumerations

Example:

typedef enum logic [3:0] { IDLE=0, START, STAGE[4:6], BLAH, STAGE[3] } states_e;
states_e state, next_state;

Is the equivalent of writing:

parameter [3:0] IDLE   = 4'd0,
                START  = 4'd1,
                STAGE4 = 4'd2,
                STAGE5 = 4'd3,
                STAGE6 = 4'd4,
                BLAH   = 4'd5,
                STAGE0 = 4'd6,
                STAGE1 = 4'd7,
                STAGE2 = 4'd8;

Creating Integers:

Verilog/SystemVerilog

With IEEE Std 1364-2005 (Final version of Verilog) or IEEE Std 1800 (SystemVerilog) use reg [$clog2(c_TOTAL_ROWS)-1:0] Row_Count;

For older Verilog (IEEE Std 1364-1995 and IEEE Std 1364-2001) create a custom fuction to find the ceiling of a log base 2. Example:

function interger ceiling_log2(input integer value);
  interger local_copy;
  local_copy = value;
  ceiling_log2 = 0;
  while(local_copy!=0) begin
    ceiling_log2 = ceiling_log2 + 1;
    local_copy = local_copy >> 1;
  end
  return ceiling_log2;
endfunction
reg [ceiling_log2(c_TOTAL_ROWS)-1:0] Row_Count;

Note: Some synthesizer may have limitations

Upvotes: 5

Related Questions