Trying to find Verilog Version of $realtime (SystemVerilog function)? - verilog

I'm trying to rewrite some Verilog files to be implemented on an FPGA. This means that I need to rewrite some SystemVerilog as Verilog so it can be synthesized.
The code I'm using has realtime net types and calls the function $realtime and I have no clue how to rewrite it to be regular Verilog. A snippet of this code can be seen below:
realtime t_pad_current_transition,t_pad_prev_transition;
realtime t_filt_in_h_current_transition,t_filt_in_h_prev_transition;
realtime pad_pulse_width, filt_in_h_pulse_width;
always #(PAD)
begin
if (^PAD !== 1'bx)
begin
t_pad_prev_transition = t_pad_current_transition;
t_pad_current_transition = $realtime;
pad_pulse_width = t_pad_current_transition - t_pad_prev_transition;
end
else
begin
t_pad_prev_transition = 0;
t_pad_current_transition = 0;
pad_pulse_width = 0;
end
end
I've thought about changing them to registers, but that still doesn't fix the issue of the $realtime line.

This code is in Verilog already. It is not synthesizable.
realtime is just a synonym for real. real is not synthesizable.
if (^PAD !== 1'bx) is not synthesizable.
$realtime is not synthesizable

Related

Combinational way of implementing a CAM in verilog

I'm trying to implement a cache and index lookup memory in SystemVerilog. It's a simple CAM + circular buffer. The interface is:
input rst_n;
input clk;
input [WORD_BITS-1:0] inp;
input rd_en;
input wr_en;
output logic [DEPTH_BITS-1:0] index;
output logic index_valid;
reg [WORD_BITS-1:0] buffer[$pow(2, DEPTH_BITS)];
reg [DEPTH_BITS-1:0] next;
There's basic async reset code. There's a synchronous block that stores inp in buffer and advances next whenever wr_en is high.
Now I'm trying to come up with an efficient and readable way of finding the index of inp when rd_en is high. It seems this could be completely combinational except when clocking the result into the index output. The way I'm visualizing it in my head is to xor inp with all of the buffer locations (it will be fairly small, perhaps 64 entries) then if that is equal to 0 the entry was found. Then a block to arbitrarily choose one of the indices with a 0 value. This is where is differs from a traditional CAM, there could be multiple entries for the same value but I really only need the index of one of those and it doesn't matter which one.
Any thoughts on how to do this in System Verilog (2012)? I know I can loop through all the memory locations synchronously and save a bunch of area but I'd rather it be fast than small. I'm targeting FPGAs. (initially inexpensive Lattice and maybe Xilinx parts) I know a few of the Lattice parts actually have CAM blocks but this is for cases where that isn't available.
Following up on a suggestion from another forum, the following seems to work well.
always_comb begin
index_valid = 0;
for (int i=0; i < 64; i=i+1) begin
if (rd_en) begin
if (inp == buffer[i]) begin
index = i;
index_valid = 1'b1;
end
end
end
end

Are these lines legal in Verilog?

I am working on RTL coding of rs232 protocol in verilog I wrote the Tx/Rx codes in two different files.
I wanted to know whether these lines[as shown below] are legal in verilog. By legal I mean do they produce synthesizable output? I have initialized count_tx to 12. Basically, I want serial output through dataframe_tx. I know we can do this through the logical shift left, but I used this method.
In the waveform analyzer, I could see dataframe_tx always zero. That is where I started doubting these lines.
.
.
.
S_SENDING:begin
dataframe_tx = temp_tx[12-count_tx];
count_tx = count_tx - 1;
if(count_tx)
next_tx = S_SENDING;
else begin
next_tx = S_DONE;
done_tx = 1'b1;
end
end
.
.
.
.
To answer your question: The code fragment you posted consists of legal SystemVerilog constructs.
If one adds proper declarations of the objects you are referencing, adds the obvious missing case statement and wraps the whole in an always_ff block it will compile and thus generate synthesizable code.
You asked about syntax and not semantics. Will it work? Hard to tell from the fragment. But the intent of your if statement seems to be checking if the vector is non-zero. Consider if( |count_tx ) instead.
I added few lines to your code to make if syntactically OK. I also tool the liberty to change the assignments to non-blocking as these would be otherwise inferred by the tool. Still remains as a fragment but I hope it may help.
module Sandbox(
input logic clk
// inputs and outputs ...
);
logic dataframe_tx;
logic [12:0] temp_tx;
logic done_tx;
logic [3:0] count_tx;
enum {S_SENDING, S_DONE} next_tx;
always_ff #(posedge clk) // as an example
begin
case (next_tx)
// something ...
S_SENDING: begin
dataframe_tx <= temp_tx[12-count_tx];
count_tx <= count_tx - 1;
if( |count_tx )
next_tx <= S_SENDING;
else begin
next_tx <= S_DONE;
done_tx <= 1'b1;
end
end
// something ....
S_DONE: /* your code */;
endcase
end
endmodule
Good luck!

How to prevent ISE compiler from optmizing away my array?

I'm new to Verilog, ISE, FPGAs. I'm trying to implement a simple design into an FPGA, but the entire design is being optimized away. It is basically an 2D array with some arbitrary values. Here is the code:
module top(
output reg out
);
integer i;
integer j;
reg [5:0] array [0:99][0:31];
initial begin
for(i=0;i<100;i=i+1) begin
for(j=0;j<32;j=j+1) begin
array[i][j] = j;
out = array[i][j];
end
end
end
endmodule
It passes XST Synthesis fine, but it fails MAP in the Implementation process. Two Errors are given:
ERROR:Map:116 - The design is empty. No processing will be done.
ERROR:Map:52 - Problem encountered processing RPMs.
The entire code is being optimized away in XST. Why? What am I doing wrong?
The reason your design is being synthesized away is because you have not described any logic in your module.
The only block in your design is an initial block which is typically not used in synthesis except in limited cases; the construct mainly used for testbenches in simulation (running the Verilog through ModelSim or another simluator).
What you want is to use always blocks or assign statements to describe logic for XST to synthesize into a netlist for the FPGA to emulate. As the module you provided has neither of these constructs, no netlist can be generated, thus nothing synthesized!
In your case, it is not entirely clear what logic you want to describe as the result of your module will always have out equal to 31. If you want out to cycle through the values 0 to 31, you'll need to add some sequential logic to implement that. Search around the net for some tutorials on digital design so you have the fundamentals down (combinational logic, gates, registers, etc). Then, think about what you want the design to do and map it to those components. Then, write the Verilog that describes that design.
EDIT IN LIGHT OF COMMENTS:
The reason you are get no LUT/FF usage on the report is because the FPGA doesn't need to use any resources (or none of those resources) to implement your module. As out is tied to constant 31, it will always have the value of 1, so the FPGA only needs to tie out to Vdd (NOTE that out is not 31 because it is only a 1-bit reg). The other array values are never used nor accesses, so the FPGA synthesized them away (ie, not output needs to know the value of array[0][1] as out is a constant and no other ports exist in the design). In order to preserve the array, you need only use it to drive some output somehow. Heres a basic example to show you:
module top( input [6:0] i_in, // Used to index the array like i
input [4:0] j_in, // Used to index the array like j
output reg [5:0] out // Note, out is now big enough to store all the bits in array
);
integer i;
integer j;
reg [5:0] array[0:99][0:31];
always #(*) begin
// Set up the array, not necessarily optimal, but it works
for (i = 0; i < 100; i = i + 1) begin
for (j = 0; j < 32; j = j + 1) begin
array[i][j] = j;
end
end
// Assign the output to value in the array at position i_in, j_in
out = array[i_in][j_in];
end
endmodule
If you connect the inputs i_in and j_in to switches or something and out to 6 LEDs, you should be able to index the array with the switches and get the output on the LEDs to confirm your design.

Getting strange error in verilog (vcs) when trying to use if/else blocks

I am trying to write an "inverter" function for a 2's compliment adder. My instructor wants me to use if/else statements in order to implement it. The module is supposed to take an 8 bit number and flip the bits (so zero to ones/ones to zeros). I wrote this module:
module inverter(b, bnot);
input [7:0] b;
output [7:0]bnot;
if (b[0] == 0) begin
assign bnot[0] = 1;
end else begin
assign bnot[0] = 0;
end
//repeat for bits 1-7
When I try and compile and compile it using this command I got the following errors:
vcs +v2k inverter.v
Error-[V2005S] Verilog 2005 IEEE 1364-2005 syntax used.
inverter.v, 16
Please compile with -sverilog or -v2005 to support this construct: generate
blocks without generate/endgenerate keywords.
So I added the -v2005 argument and then I get this error:
vcs +v2k -v2005 inverter.v
Elaboration time unknown or bad value encountered for generate if-statement
condition expression.
Please make sure it is elaboration time constant.
Someone mind explaining to me what I am doing wrong? Very new to all of this, and very confused :). Thanks!
assign statements like this declare combinatorial hardware which drive the assigned wire. Since you have put if/else around it it looks like you are generating hardware on the fly as required, which you can not do. Generate statements are away of paramertising code with variable instance based on constant parameters which is why in this situation you get that quite confusing error.
Two solutions:
Use a ternary operator to select the value.
assign bnot[0] = b[0] ? 1'b0 : 1'b1;
Which is the same as assign bnot[0] = ~b[0].
Or use a combinatorial always block, output must be declared as reg.
module inverter(
input [7:0] b,
output reg [7:0] bnot
);
always #* begin
if (b[0] == 0) begin
bnot[0] = 1;
end else begin
bnot[0] = 0;
end
end
Note in the above example the output is declared as reg not wire, we wrap code with an always #* and we do not use assign keyword.
Verliog reg vs wire is a simulator optimisation and you just need to use the correct one, further answers which elaborate on this are Verilog Input Output types, SystemVerilog datatypes.

Generate block inside case statement in verilog or system verilog

Is there a way in Verilog or SystemVerilog to insert generate statement inside case statement to generate all the possible input combinations. For example a typical use case would be for a N:1 mux.
case(sel)
generate
for(i = 0; i < N; i += 1)
i: out = q[i];
endgenerate
endcase
I tried this, but the tool gives error. An alternate syntax is available which is
out <= q[sel];
But, my tool is not understanding this(the mux is fully decoded) and generating combinational loops. I can use if statement to get the expected mux. But, I was wondering if there was a better way to do it.
You can't mix a for and a case like that. If you're just trying to write a multiplexer, have a look at this older question: How to define a parameterized multiplexer using SystemVerilog
The only difference there is that the select signal is supposed to be onehot encoded. For your case you would have:
always_comb begin
out = 'z;
for (int i = 0; i < N; i++) begin
if(sel == i)
out = q[i];
end

Resources