Converting from VHDL to Verilog, specific cases

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

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

Replacement for others:

I know that to assign signals in Verilog you can do:

data <= 'b0;

      

This sets all bits of the data to zero, and if the data changes its width, it still works. A neat trick, but what about when instantiating the module and binding the input to zero? For example.

   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 width based on generics, so if the port width changes whatever is required, it's a quick update to the generic and 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 is giving me trouble. Is this the best way to do this, to create a combination block always and use a case-statement for the index? It looks like a lot of code. Using the operator ?

can lead to some illegible code, so I prefer not to do this for a long time while chaining / else.

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 statement in Verilog? I often use them on my VHDL FIFOs to check for overflow / underload conditions. For example.

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

      

Generate blocks:

In VHDL, it is nice to be able to generate a block of code based on a common one, or delete it entirely if there is none. For example.

  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;

      

List of machine states:

In Verilog, do I really need to create parameters

for each individual state? If this is the best way to do it, I'll do it, but it seems like a lot. I love that in VHDL you can create a type that simply contains each state and then create a machine state signal of that type.

Creating integers:

I often 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? Should I take database 2 from c_TOTAL_ROWS to find the max width and then determine reg

based on that? It looks like a lot of work. I believe Verilog creates 32-bit integers by default, but I don't want to generate additional logic if I don't need it. I also like that if I go over the expected range, my Modelsim will crash.

+3


source to share


1 answer


Not everything can be directly translated into Verilog.

Replacement for others:

Verilog

'b0

should work with port restrictions. Warnings should compile, not errors. Some simulators try to be backward compatible with IEEE Std 1364-2005 where 'b0

is the output 32'b0

. According to IEEE Std 1364-2005 and section 3.5.1 this is a 32-bit max. Simulators can lag behind the standard. It is a simulator limitation if the port module instance .Data('b0),

results in a compilation error.

SystemVerilog

SystemVerilog adds filling constants '0

, '1

, 'x

and 'z

. '0

, 'x

and are the 'z

same as IEEE Std 1364-2005 'b0

, 'bx

and 'bz

with one smaller character. 'b1

is {(N-1){1'b0},1'b1}

where '1

is {N{1'b1}}

, where N is the width of the target vector / packed array.

Replacement for attributes:

Verilog

Cannot 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 chaining / else:

Verilog / SystemVerilog (for both)

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

      

Works functional, but when synthesized they may not give the best timing and area. When some synths see ?:

, they will always generate a 2 to 1 mux; if they see a chain nested ?:

, it will create a chain of 2-to-1 multiplexes, even if there is a 4-to-1 mux (or other types of multiplexers).

This prints a little more, but it 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

      

Statement:

Verilog

Verilog has no statements built into the language. Making some for checkers is not difficult (for example, non-overlapping parallel validation can be done with an always block), but flagging an error for the simulator can be a little more difficult. Typically the global error counter is incremented with errors and the simulation is aborted with $finish

if the user-defined error limit is reached. There might be a PLI / VPI solution or something specific simulator.

SystemVerilog

SystemVerilog has two main types of assertions; simultaneous and immediate. Immediately exist inside a procedural block (i.e. at the beginning) for example:

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

      

Parallel statements are executed in the module scope, outside the procedural block side. They use a sync link.



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

      

Refer to IEEE Std 1800-2012 & sect; 16. Statements for further clarifications and examples.

Note. If using UVM, use `uvm_error

instead$error

Creating blocks:

Verilog / SystemVerilog

Generate Blocks have been added to Verilog IEEE Std 1364-2001. generate

- endgenerate

are actually optional, but make a good visual reference. See IEEE Std 1800-2012 & sect; 27. Generate structures 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, target addressing would also work in Verilog / System Verilog: w_XNOR = ~^r_LFSR[g_Num_Bits-:2];

IEEE Std 1800-2012 & section; 11.5.1

List of machine states:

Verilog

Have to use it parameter

here if you want to use names instead of storing indices. It is possible to allow multiple parameters in one of the operators, but the identifier must still determine its value.

SystemVerilog

Enumeration is supported. See IEEE Std 1800-2012 & sect; 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;

      

Equivalent to 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 (Verilog final) or IEEE Std 1800 (SystemVerilog) use reg [$clog2(c_TOTAL_ROWS)-1:0] Row_Count;

For older Verilogs (IEEE Std 1364-1995 and IEEE Std 1364-2001) create a custom fuction to find the log base ceiling 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 synthesizers may have limitations

+2


source







All Articles