What is the difference between these verilog codes? - verilog

I'm was following a tutorial to blink a led in my fpga.
These are the codes presented :
1)
module LED (
input [17:0] SW,
output reg [17:0] LEDR
);
assign led = switch;
endmodule
2) --------
module LED (
input [17:0] SW,
output reg [17:0] LEDR
);
always #(*)
led = switch;
endmodule
3) ---------
module LED (
input CLOCK_50,
input [17:0] SW,
output reg [17:0] LEDR
);
always #(posedge CLOCK_50)
LEDR = SW;
endmodule

Your first example uses continuous assignment to set the value of led to the value of switch. It's like connecting led and switch directly with a wire. Whenever switch changes, led also changes.
Your second example does the same thing but uses an always block. always blocks have a sensitivity list, which contains signals that will trigger the block to run. In this case, it's *, meaning that it triggers any time any of the signals in the blocks change. I believe this is identical to your first example.
Your third example uses sequential logic to set LEDR to SW. In this case, the always block triggers only when the CLOCK_50 signal goes high from a non-high state. If CLOCK_50 never rises, LEDR is never set to any value.
By the way, I don't think your first or second examples are synthesizable. I think led and switch should be LEDR and SW.
These articles give a better description of the concepts in your examples:
Assignments : http://verilog.renerta.com/mobile/source/vrg00005.htm
Always Blocks: http://www.asic-world.com/verilog/verilog_one_day3.html

Related

Edge triggered flip flop behaving like a transparent latch when sensitivity list has two rising edges

Trying this on a Terasic DE10-Lite, programmed with Quartus Prime Lite Edition.
SW[0] is a switch. LEDR[0] is an LED. KEY[0] is a push button. The push button is active low.
I want to model a flip flop that stores SW[0] in register r0 and displays it in LEDR[0] when KEY[0] delivers a rising edge.
The following works as expected:
module flipfloptest (
input [9:0] SW,
input [1:0] KEY,
output [9:0] LEDR);
reg r0;
assign LEDR[0] = r0;
always #(posedge(~KEY[0]))
r0 <= SW[0];
endmodule
I now add another push button, KEY[1], to the sensitivity list with the intention that pushing either down will set the flip flop.
module flipfloptest (
input [9:0] SW,
input [1:0] KEY,
output [9:0] LEDR);
reg r0;
assign LEDR[0] = r0;
always #(posedge(~KEY[0]) or posedge(~KEY[1]))
r0 <= SW[0];
endmodule
This behaves like a latch (i.e. no longer edge triggered). LEDR[0] immediately reflects the state of SW[0] without the need to press either KEY[0] or KEY[1]. Pressing one or both does not affect behavior in any way.
Clearly, I don't understand the meaning of this sensitivity list. What is the correct interpretation?
More context: I can get the desired behavior using a clock and state machine as shown below. My question is why the sensitivity list isn't behaving intuitively.
module flipfloptest (
input MAX10_CLK1_50,
input [9:0] SW,
input [1:0] KEY,
output [9:0] LEDR);
reg [1:0] tic0, tic1;
reg r0;
assign LEDR[0] = r0;
always #(posedge MAX10_CLK1_50) begin
case (tic0)
0: tic0 = (~KEY[0])?1:0;
1: tic0 = (~KEY[0])?2:0;
2: tic0 = (~KEY[0])?2:0;
endcase
case (tic1)
0: tic1 = (~KEY[1])?1:0;
1: tic1 = (~KEY[1])?2:0;
2: tic1 = (~KEY[1])?2:0;
endcase
if (tic0==1 | tic1==1)
r0 <= SW[0];
end
endmodule
Synthesis tools only recognize certain Verilog coding patterns. Refer to synthesizable constructs. The documentation for your Quartus tool set should describe what coding styles are supported.
Your 1st and 3rd code examples adhere to the synthesizable coding style, whereas your 2nd example does not. You should look at the log files that your synthesis tools created: there should be messages in there warning you about unintended latches.
The code in your 2nd example is unusual. Perhaps your synthesis tool did not know what to do with it, and it just decided to give you a latch. Unfortunately for you, that is not how your code simulates.
This code:
always #(posedge(~KEY[0]) or posedge(~KEY[1]))
r0 <= SW[0];
can be simplified as:
always #(negedge KEY[0] or negedge KEY[1])
r0 <= SW[0];
r0 will be updated with SW[0] every time you get a negedge of either KEY[0] or KEY[1]. That does not behave like a latch. But, as I said, this code does not adhere to typical synthesis coding style.

What is best way to call another module?

I'm confused about connection, I want to use ALU to call RippleCarry module, and I need to do branch without always block and Procedure Assignment.
I don't know what method is best. I see others have written in TestBench.v or ALU.v.
Here's my code.
ALU.v
module ALU( Signal, a, b, Output );
input [31:0] a, b;
input [5:0] Signal;
output [31:0] Output;
// write here ? or write into test bench?
// if Signal is 6'd35, do RippleCarry.
/*RippleCarry RC( .a(a), .b(b), .Sum(Output) ); */
endmodule
RippleCarray.v
module RippleCarry(
input [31:0] a, b,
input Cin,
output Cout,
output [31:0] Sum
);
In verilog, modules are not called, but instantiated. Unlike traditional programming, verilog is a hardware descriptive language; meaning it is code describing hardware, not specifying instructions to be run by a cpu as you do in typically programming languages. Hardware doesn't materialize and dematerialize when signals take on different values; the control signals simply define which of many different data paths is connected between input and output.
In your case, you wouldnt write something like this:
module ALU(...)
if (Signal == 6'd35) begin
RippleCarry RC(...);
end
endmodule
Since Signal is a control line that changes value as the hardware runs, this would imply the ripple carry adder exists when the Signal is 35 and disappears when it's not.
Instead, the adder should be instantiated, it exists in the design and it always there. The problem now is to direct it's output to the output of the ALU only when Signal is 35.
module ALU(input [5:0] Signal,
input [31:0] a, b,
output reg [31:0] Output); // Note, I made Output a reg so I can use always, it doesn't mean it's actually a register
wire [31:0] rcOutput;
// Instantiate the RC adder so it exists in the hardware
RippleCarry RC(.a(a), .b(b), .Sum(rcOutput));
// Direct the output of the RippleCarry adder to the output only when signal is 35, otherwise just leave it at 0.
// Use switch here to make it easy to add more operations later
always #(*) begin
Output = 32'd0; // default
case (Signal)
6'd35: Output = rcOutput; // rc add
endcase
end
endmodule
Edit: I see now you want to do it without using always or assign, which doesn't change the fundamental design but makes it more obscure and less scalable, which is why I'm leaving the above as a reference. In the case we only have one op code for signal, we can simply implement the logic that compares signal to 35 and masks output if not equal in gates:
// Replace the always block with the below, though it's certainly not as nice, it's a possible implementation of that always block in gates
wire [5:0] SignalN;
wire SignalIs35;
not g1[5:0](SignalN, Signal);
// 35 is 100011 in binary, so see if Signal is that value
and g2(SignalIs35, Signal[5], SignalN[4], SignalN[3], SignalN[2], Signal[1], Signal[0]);
and g3[31:0](Output, rcOutput, {32{SignalIs35}});

Seeing X for values in one module

I have two modules 'wired' together. One is a simple sequence detector and one is a counter.
Here are the two signatures of the methods:
module Detector1010 (input [3:0] co_in, input j, clk, rst, output w, output reg init, output reg en);
module counter (input clk, rst, en, init, output reg [3:0] co );
Essentially that output register 'co' in the counter is intended to be readable from the Dector1010 module (hence the co_in) variable. The reason for that is I want to be able to detect when the co reaches a certain value, to perform some sort of action.
Within 'Detector1010' there is always block which checks the value of 'co_in'
$display("sleep! %d", co_in);
if(co_in == 4'b1111) begin
//reached 16!
$display("reached 16!");
end
Here I am just waiting for the counter value to reach 16 and printing what it is each time the always block executes. (How often does that execute? It seems to run just constantly and not on a clock.. I guess the whole point is its always running?). However by display instead prints:
"sleep! x"
As if the actual value of that register does not get passed in. I was using a wire to connect the two modules, so I thought this sort of input is allowed:
wire [3:0] co;
wire init;
wire en;
assign co = 4'b0000;
Detector1010 det(co, j, clk, rst, w, init, en);
counter cnt(clk, rst, en, init, co);
as I figured the 'co' variable would just work as a databus between the detector and the counter modules. I guess I am misunderstanding how that variable works? Not really sure what I am doing wrong here!
I can post the whole code example. I was trying to just keep it concise.
You have contention on the co signal which results in x. Remove this line:
assign co = 4'b0000;
Your counter module drives the co output signal, but your testbench continually drives it to 0, at all times starting at time 0. co would normally be initialized inside the counter module.

How to assign initial value to an input reg: Design compiler delete the assignment

I'm newbie in ASIC design. I have a design with for example two inputs a ,b. I'm using the following code for initialize these two signals. But the Design compiler generating a warning that the register "a" is a constant and will be removed. When I'm trying to do post-synthesis simulation these two signals are all 'z'. So how can I apply initial signal assignment to avoid such a problem?
always #(posedge(clk) or posedge (rst)) begin
if (rst) begin
a<=4d'5;
b <=4'd10;
end
end
While describing hardware system, you need to consider that input signals to your module comes from another module/system and their values are decided by that signals. Inputs to any module can only be wire type.
You can think of a module as a box that has inputs and outputs. The values of output signals are decided by input signal + logic inside the box. However, the module cannot decide what its inputs should be. It is only possible if there is feedback, and even in that case it would depend on other signals that are outside of the module's control.
As a result, output signals can be declared as output reg but the same is not true for inputs. However there is solution to your problem, I think what you want can be designed using the following method:
module your_module(
input clk,
input rst,
//other inputs and outputs that you might need
input [3:0] a,
input [3:0] b
);
//define registers
reg [3:0] a_register;
reg [3:0] b_register;
/*
These registers are defined to make it possible to
to give any value to that logics when posedge rst
is detected, otherwise you can use them as your
input logics
*/
//use initial block if you need
always#(posedge clk or posedge rst) begin
if(rst) begin
a_register <= 4'd5;
b_register <= 4'd10;
end
else
begin
a_register <= a;
b_register <= b;
// and use a_register and b_register as you want to use a and b
end
end
endmodule

Verilog code runs in simulation as i predicted but does not in FPGA

I try to write an UART transmitter module. It gets data from data[7:0] and then sends it serially via Tx. I wrote a module named Tester for testing transmitter. It simulates in Isim as I predicted but does not in Spartan-6. I watched the Tx pin with osciloscope, I saw only logic 1. I could not detect the problem. What have I done incorrectly?
module Tester(
clk,
data,
oclk,
Tx
);
input wire clk;
output reg [7:0] data;
output wire oclk;
output wire Tx;
assign oclk = clk;
initial begin
data<=8'b11001010;
end
UartTransmitter UT(.clk(clk),.data(8'b11001010),.Tx(Tx),.transmit(1'b1));
endmodule
module UartTransmitter(
//Inputs
clk,
reset,
data,
transmit,
//Output
Tx
);
input wire clk;
input wire reset;
input wire [7:0] data;
input wire transmit;
output reg Tx;
reg [16:0] counter;
reg durum;
reg s_durum;
reg sendbyone;
reg [10:0]buffer;
reg [3:0]nbitstransmitted;
parameter IDLE = 1'b0;
parameter TRANSMITTING = 1'b1;
initial begin
counter=0;
Tx=1;
s_durum = IDLE;
durum=IDLE;
sendbyone=0;
buffer=0;
nbitstransmitted=0;
end
always #(posedge clk) begin
counter<=counter+1;
if(counter>=13019) begin
counter<=0;
sendbyone<=1;
end else begin
sendbyone<=0;
end
durum<=s_durum;
end
always #(*) begin
s_durum=durum;
if((durum==IDLE) && (transmit==1)) begin
buffer={1'b1,^data,data,1'b0};
s_durum=TRANSMITTING;
end
else if(durum==TRANSMITTING && (sendbyone==1)) begin
if(nbitstransmitted<10) begin
Tx=buffer[nbitstransmitted];
nbitstransmitted=nbitstransmitted+1;
end else if(nbitstransmitted==10)begin
Tx=buffer[10];
nbitstransmitted=0;
s_durum=IDLE;
end
end
end
endmodule
buffer, Tx and nbitstransmitted are inferred latches. Latches are inferred when a variable is not guaranteed assignment with in an combinational block (always #*). buffer is a simple latch because the control logic is coming from flops. Tx will be simple latch after nbitstransmitted is changed to a flip-flop. The main issue is nbitstransmitted because it has feedback. With the current design in simulation if data changes when durum==TRANSMITTING && sendbyone then nbitstransmitted will increment. Even if data is from a flop in the same clock domain, on the FPGA there can be skew on each bit and trigger multiple updates.
Complex latches are prone to race conditions and use up lots of area. As an example, I copied the provide code to EDAplayground and synthesized it with Yosys 0.3.0. With the "show diagram" enabled it will show a large number of gates used with sufficient latch feedback. Try running here (Sorry I cannot upload the diagram, maybe someone else can)
The solution is easy by following the same strategy already used for durum; create a next state variable. sticking with the current convention, create new variables for buffer, Tx and nbitstransmitted with the respected names with a s_ prefix. The combinational block (always #*) will assign the s_ signals and should default to there respected counter part. And the sequential block (always #(posedge clk)) will assign the flops by their respected s_. The flops with remove the asynchronous feedback and simplify the design. For cleaner design, I moved the counter<=counter+1; into the else condition and commented out if(nbitstransmitted==10). Try running here
Other note not related to the issue:
The reset signal is not being used. I suggest using it in the sequential block and remove the initial block. Most FPGAs support initial and most ASIC do not. I prefer using reset signals over initial blocks because it allows resetting the device without having to power cycle. Just a suggestion.

Resources