Are these lines legal in Verilog? - 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!

Related

Assigning x (dont care) to a register reset value or combinatorical output to improve area efficiency [duplicate]

This question already has answers here:
How can I assign a "don't care" value to an output in a combinational module in Verilog
(2 answers)
Closed 2 years ago.
My question is regarding FPGA design - if I have some registers in my design that I dont care what will be their reset value, can I set the reset value to x? will that improve area efficiency (will the synthesizer be able to utilize this and generate the design in a more efficient way?)
For example,
always #(posedge clk or negedge reset_n) begin
if(~reset_n) begin
reg_1 <= 'x
end
...
end
Edit:
And another question in a similar topic - assuming I have a state machine for example that I dont care what will some outputs be in some states - does setting them to 'x improve area efficiency?
for example, if I have a fsm with two states, STATE_1, STATE_2, and two outputs will the synthesis tool be able to utilize the following code:
always_comb begin
case(state):
STATE_1:begin
out_1 = 1;
out_2 = x;
end
STATE_2:begin
out_1 = x;
out_2 = 0;
end
end
better than this:
always_comb begin
case(state):
STATE_1:begin
out_1 = 1;
out_2 = 0;
end
STATE_2:begin
out_1 = 0;
out_2 = 0;
end
end
(under the assumption that I dont care what is out_2 in STATE_1, and what is out_1 in STATE_2).
Thanks
Using 'x in sequantial logic
Yes, Verilog-wise, you could use this syntax. However, in your particular example, it does not really make sense to do this and you could consider it to be a bad coding practive. Instead of explicitly assigning 'x, you can also omit the asynchronous reset.
The following two processes will synthesise to the same flip-flop. I would personally recommend to use the latter style.
// Assigning 'x to tell synthesis tool that there is no reset value
always #(posedge clk or negedge reset_n)
if(~reset_n)
reg_1 <= 'x;
else
reg_1 <= reg_1_next;
// Omitting the asynchronous reset from the sensitivity list to tell
// synthesis tool that there is no reset
always #(posedge clk)
reg_1 <= reg_1_next;
In general: if you have different variables which must be either resetable or non-resetable, you should split their assignment into different always-blocks. This generally makes your code better readable. See the example below:
// Do NOT do this
always #(posedge clk or negedge reset_n)
if(~reset_n)
begin
vld <= 1'b0;
reg_1 <= 'x;
end
else
begin
vld <= vld_next;
reg_1 <= reg_1_next;
end
// Do this
always #(posedge clk or negedge reset_n)
if(~reset_n)
vld <= 1'b0;
else
vld <= vld_next;
always #(posedge clk)
reg_1 <= reg_1_next;
Bonus
Having said that, there are cases where it could make sense to assign 'x in the reset condition to tell the synthesis tool to not generate resetable flops for particular variables. Please take a look at this answer: https://stackoverflow.com/a/21477457/7949378
Lets create an example, based on this answer. Lets say you have a struct with 1 valid-signal (vld) and 2 data signals (data_a and data_b). The data is only valid when vld is 1'b1. In other words, we can save area by only resetting vld and not resetting data_a and data_b.
Now, we want to use the full potential of structs, and simply assign the full struct instead of the seperate members (see struct_example_q <= struct_example_next;). This means we cannot split this always-block into two seperate processes (like I recommened before). In that case, we must explicitly tell the synthesis tool to not reset the data signals.
See the code below:
typedef struct {
logic vld;
logic [31:0] data_a;
logic [31:0] data_b;
} struct_example_t;
struct_example_t struct_example_next;
struct_example_t struct_example_q;
always #(posedge clk or negedge reset_n)
if (!reset_n)
begin
/**
* Only reset the valid-bit
* We could use '{default:'x} to simplify this even further
**/
struct_example_q.data_a <= 'x;
struct_example_q.data_b <= 'x;
struct_example_q.vld <= 1'b0;
end
else
begin
struct_example_q <= struct_example_next;
end
Using 'x in combinatorial logic
Lets first look at your RTL:
always_comb begin
case(state):
STATE_1:begin
out_1 = 1;
out_2 = x;
end
STATE_2:begin
out_1 = x;
out_2 = 0;
end
end
I want to note that this is not really the best example. Assuming that the FSM is full—i.e., that STATE_1 and STATE_2 are the only two states state can take—you would achieve exactly the same with the code below, assuming you don't case anyway about out_1 and out_2 in the other states.
always_comb begin
out_1 = 1;
out_2 = 0;
end
Now, for the sake of the example, lets assume that we cannot rewrite this. In that case, you should set default values before your case-statement. This prevents the synthesis logic from infering latches in your don't-care state, but it also helps you to not run into issues with 'x once you start doing gate-level simulations (GLS). Using your example, you RTL would look like the code below. (Again note that the case here is kind of redundant.)
always_comb begin
out_1 = 1;
out_2 = 0;
case(state):
STATE_1:begin
out_1 = 1;
end
STATE_2:begin
out_2 = 0;
end
end
You will see that this strategy makes sense once you have more elaborate FSMs.
Bonus
I want to give an example where using unique or priority can make sense (instead of using 'x as default value). Take a look at the RTL below and assume that select == 3'b0 will never occur:
always_comb
begin
out_1 = 'x;
case (1'b1)
select[0]: out_1 = a & b;
select[1]: out_1 = a ^ b;
select[2]: out_1 = a | b;
endcase
end
Setting a default value for out_1 will prevent the logic from inferring a latch (since it does not know that select == 3'b0 can never occur). Furthermore, the 'x here will help the synthesis tool to optimize this logic (not necessarily w.r.t. area!). However, as we discussed before, using 'x is generally considered to be bad practice.
Instead of using a default value, you can use the priority keyword to tell the synthesis tool that all valid cases have been listed and that the tool must evaluate your cases in order. Because of that, the following case will also be considered as full:
always_comb
priority case (1'b1)
select[0]: out_1 = a & b;
select[1]: out_1 = a ^ b;
select[2]: out_1 = a | b;
endcase
If you, additionally, can be sure that select is a onehot signal ($countones(select) == 1), you can use the unique keyword. This will tell the synthesis tool that this is full-parallel case
always_comb
unique case (1'b1)
select[0]: out_1 = a & b;
select[1]: out_1 = a ^ b;
select[2]: out_1 = a | b;
endcase
Note that simulators will trry to enforce these assumptions by throwing errors at you if you violate the assumptions that are necessary to use priority or unique.

generate inside generate verilog + error near generate(veri - 1137)

Writing verilog code from quite a few days and one question I have is 'Can we write generate block inside generate block'? I am writing an RTL something like this:
Where 'n' is a parameter.
reg [DATA_WIDTH:0] flops [n-1:0];
generate
if (n > 0) begin
always #(posedge clk) begin
if (en) begin
flops[0] <= mem[addr];
end
end
generate
genvar i;
for (i = 1; i <= n ; i = i + 1) begin
always #(posedge clk) begin
flops[i] <= flops[i-1];
end
end
endgenerate
always #(flops[n - 1])
douta = flops[n - 1];
else
always #(posedge clk) begin
if (en) begin
primary_output = mem[addr];
end
end
end
endgenerate
While compiling the above code, I am getting :
ERROR: syntax error near generate (VERI-1137)
Not sure why. Purpose of this RTL is to create an pipeline of 'n' flops at the output side of the design.
Lets say n is 2, then circuit should become :
flop1-> flop2-> primary output of design
flop1 and flop2 are newly created flops.
You are a long long way from where you should be.
Verilog is not a programming language; it is a hardware description language. You model hardware as a network of concurrent processes. Each process models a small bit of hardware such as a counter, a state machine, a shift-register, some combinational logic... In Verilog, each process is coded as an always block. So, one always statement never ever can appear inside another; that makes no sense.
Secondly, generate is quite a specialised statement. You use it when you want either a large number or a variable number of concurrent processes. That is not a common thing to need, so generate is not common, but is useful when required. You don't need a generate statement to implement a parameterisable shift-register. And, because an always block is a concurrent statement it sits inside a generate statement, not the other way round.
I don't know what your design intent is exactly, to I suspect this code does not do exactly what you want. However, it does implement a parameterisable shift-register of length n and width DATA_WIDTH+1 (did you really mean that?), enabled by the en input:
module N_FLOPS #(n = 2, DATA_WIDTH = 8) (input [DATA_WIDTH:0] dina, input clk, en, output [DATA_WIDTH:0] douta);
reg [DATA_WIDTH:0] flops [n-1:0];
always #(posedge clk)
if (en)
begin : SR
integer i;
flops[0] <= dina;
for (i = 1; i <= n ; i = i + 1)
flops[i] <= flops[i-1];
end
assign douta = flops[n-1];
endmodule
http://www.edaplayground.com/x/3kuY
You can see - no generate statements required. This code conforms to this template, which suffices for any sequential logic without an asynchronous reset:
always #(posedge CLOCK) // or negedge
begin
// do things that occur on the rising (or falling) edge of CLOCK
// stuff here gets synthesised to combinational logic on the D input
// of the resulting flip-flops
end

Verilog: functionality like always & synthesizable

Is there any other functionality like always (that would only run if the sensitive signal changes and won't iterate as long as signal stays the same) which can be cascaded, separately or within the always , but is synthesizable in Verilog.
While I don't think there's a construct specifically like this in Verilog, there is an easy way to do this. If you do an edge detect on the signal you want to be sensitive to, you can just "if" on that in your always block. Like such:
reg event_detected;
reg [WIDTH-1:0] sensitive_last;
always # (posedge clk) begin
if (sensitive_signal != sensitive_last) begin
event_detected <= 1'b1;
end else begin
event_detected <= 1'b0;
end
sensitive_last <= sensitive_signal;
end
// Then, where you want to do things:
always # (posedge clk) begin
if (event_detected ) begin
// Do things here
end
end
The issue with doing things with nested "always" statements is that it isn't immediately obvious how much logic it would synthesize to. Depending on the FPGA or ASIC architecture you would have a relatively large register and extra logic that would be instantiated implicitly, making things like waveform debugging and gate level synthesis difficult (not to mention timing analysis). In a world where every gate/LUT counts, that sort of implicitly defined logic could become a major issue.
The assign statement is the closest to always you you can get. assign can only be for continuous assignment. The left hand side assignment must be a wire; SystemVerilog also allows logic.
I prefer the always block over assign. I find simulations give better performance when signals that usually update at the same time are group together. I believe the optimizer in the synthesizer can does a better job with always, but this might depend on the synthesizer being used.
For synchronous logic you'll need an always block. There is no issue reading hardware switches within the always block. The fpga board may already de-bounce the input for you. If not, then send the input through a two phase pipe line before using it with your code. This helps with potential setup/hold problems.
always #(posedge clk) begin
pre_sync_human_in <= human_in;
sync_human_in <= pre_sync_human_in;
end
always #* begin
//...
case( sync_human_in )
0 : // do this
1 : // do that
// ...
endcase
//...
end
always #(posedge clk) begin
//...
if ( sync_human_in==0 ) begin /* do this */ end
else begin /* else do */ end
//...
end
If you want to do a hand-shake having the state machine wait for a human to enter a multi-bit value, then add to states that wait for the input. One state that waits for not ready (stale bit from previous input), and the other waiting for ready :
always #(posedge clk) begin
case(state)
// ...
PRE_HUMAN_IN :
begin
// ...
state <= WAIT_HUMAN__FOR_NOT_READY;
end
WAIT_HUMAN_FOR_NOT_READY :
begin
// ready bit is still high for the last input, wait for not ready
if (sync_human_in[READ_BIT])
state <= WAIT_HUMAN_FOR_NOT_READY;
else
state <= WAIT_HUMAN_FOR_READY;
end
WAIT_HUMAN_FOR_READY :
begin
// ready bit is low, wait for it to go high before proceeding
if (sync_human_in[READ_BIT])
state <= WORK_WITH_HUMAN_INPUT;
else
state <= WAIT_HUMAN_FOR_READY;
end
// ...
endcase
end

Using if-else and foor loop inside an always block

I want to use if-else and for loop inside an always block. I don't want those if-else to be executed again and again, so I don't want to connect always with either posedge clkor negedge clk.
I want them to be executed only once. I not only want to simulate but I want to synthesize on to Spartan Board aswell.
always # (**what I should add here**)
begin
if(condition)
else
end
For simulations to execute some thing once you can use initial but this is not a synthesizable:
reg x;
initial begin
if(condition) begin
x = 1'b0 ;
end
else begin
x = 1'b1 ;
end
end
To answer the general question always #(**what I should add here**) Most modern verilog simulators will allow the use of * which will trigger the block (always begin to end) when any right hand side argument changes of any condition of selection logic.
always #* begin
if(condition)
x = y ;
else
x = ~y ;
end
older simulators would require you to list the variables you needed to trigger on, in a list. always #(condition, y)
If there is only 1 variable being selected an assign on a wire type might be better, but this can not be limited to being 'executed once', but would be a suitable choice from your question. Not sure about suitability for FPGA's though
wire [3:0] x ; //4 bit wire
//(condition) ? value if true : value if false ;
assign x = (condition) ? 4'b1010 : 4'b0100 ;
module oneShot(in, out, enable, reset);
input in;
input enable;
input reset;
output reg out;
reg once_only;
always # (posedge enable) begin
if (reset) begin
once_only <= 0;
end
else if (once_only == 0) begin
out <= calc_out; // or whatever processing you want
once_only <= 1;
end
end
always #(*) begin
// calculate ouput here always
calc_out = 1 + 7 +100+ in;
end
endmodule
You can't have those if statements calculate only once. It's hardware, it'll always calculate. But you can hold the output steady after it's been calculated once. You are still trying to write a software function and put it in to hardware rather than describe hardware which will solve your problem. I can't see that you'll get a decent design this way. Sure you'll be able to make some small pieces and synthesise them (eventually), but a full design??

Verilog code simulates but does not run as predicted on FPGA

I did a behavioral simulation of my code, and it works perfectly. The results are as predicted. When I synthesize my code and upload it to a spartan 3e FPGA and try to analyze using chipscope, the results are not even close to what I would have expected. What have I done incorrectly?
http://pastebin.com/XWMekL7r
Your problem is with lines 13-16, where you set initial values for state registers:
reg [OUTPUT_WIDTH-1:0] previousstate = 0;
reg [OUTPUT_WIDTH-1:0] presentstate = 1;
reg [6:0] fib_number_cnt = 1;
reg [OUTPUT_WIDTH-1:0] nextstate = 1;
This is an equivalent to writing an "initial" statement assigning these values, which isn't synthesizable -- there is no such thing as a default value in hardware. When you put your design inside an FPGA, all of these registers will take on random values.
Instead, you need to initialize these counters/states inside your always block, when reset is high.
always #(posedge clk or posedge reset)
if (reset) begin
previousstate <= 0;
presentstate <= 1;
... etc ...
end
Answer to the follow-up questions:
When you initialize code like that, nothing at all happens in hardware -- it gets completely ignored, just as if you've put in a $display statement. The synthesis tool skips over all simulation-only constructs, while usually giving you some kind of a warning about it (that really depends on the tool).
Now, blocking and non-blocking question requires a very long answer :). I will direct you to this paper from SNUG-2000 which is probably the best paper ever written on the subject. It answers your question, as well as many others on the topic. Afterward, you will understand why using blocking statements in sequential logic is considered bad practice, and why your code works fine with blocking statements anyway.
http://cs.haifa.ac.il/courses/verilog/cummings-nonblocking-snug99.pdf
More answers:
The usual "pattern" to creating logic like yours is to have two always blocks, one defining the logic, and one defining the flops. In the former, you use blocking statements to implement logic, and in the latter you latch in (or reset) the generated value. So, something like this:
wire some_input;
// Main logic (use blocking statements)
reg state, next_state;
always #*
if (reset) next_state = 1'b0;
else begin
// your state logic
if (state) next_state = some_input;
else next_state = 1'b0;
end
// Flops (use non-blocking)
always #(posedge clock)
if (reset) state <= 1'b0;
else state <= next_state;
Note that I'm using a synchronous reset, but you can use async if needed.
Lines 13-16 are correct. "reg [6:0] fib_number_cnt = 1;" is not the same as using "initial" statement. Read Xilinx synthesis guide for more detailed description of how to initialize the registers.

Resources