Verilog: Pass a vector as a port to a module - module

I have two modules
counter: Output is a vector called error_count.
lcd: Module to display the code on an LCD. Input includes clock and error_count.
Following snippet of the code is most relevant and attached below:
Top level module:
counter counter1 (..., error_count);
lcd lcd1 (..., error_count);
counter module:
module counter (..., error_count);
...
output reg [31:0] error_count = 0;
... //Update counter every clock cycle
endmodule
lcd module:
module lcd (..., error_count);
...
input [31:0] error_count;
... //error_count used to display on LCD
endmodule
What is wrong with this code? The display just prints 0 as the output. Is there anything wrong with the way I am passing the the vector?
Additional Info:
I am using the Xilinx Spartan 3E starter kit for testing this code. The LCD code is fine and I have tested it with local counter (which was reg[31:0]).

You need to declare 32-bit wire within the top-level module to connect the two ports.
wire [31:0] error_count;
If you leave this out, an implicit net is declared which is only a 1-bit wire and will not connect the vectors properly.
This mistake is a classic Verilog gotcha. The presentation here has a good explanation of this one and others:
http://www.sutherland-hdl.com/papers/2006-SNUG-Boston_standard_gotchas_presentation.pdf

Related

Verilog wire to register

I have a bidirectional bus and I can read the inputs from it into wires, but I have a hard time do logic with them and assign them back on the BUS as an output, or connecting them into registers so I could work with the values.
All help and response is appreciated.
Jozsó
There are two basic classes of variables in verilog: nets and regs. reg is used to do calculations in procedural blocks, nets are used to connect different entities such as module instances or UDPs.
So, they have different functions and different rules and operators. So, wires are connected through module instance ports and/or a continuous assign operators, which ideally represent wire connections.
The basic rule are
a net value can be used as a rhs of a register expression. So, it can be assigned to a register within a procedural (e.g. always) block.
a reg value can be assign to a net in a continuous assign operator, or in an output port connection.
net cannot be assigned any value within an always block
reg cannot be assigned with a continuous assignment
The basic scheme to work around it is the following:
wire --> always block ( reg ) --> assign (wire)
Here is an example:
module top (bus, en);
inout wire bus;
input wire en;
reg tmp;
always #*
tmp = bus;
assign bus = en ? tmp : 1'bz;
endmodule

How to declare a global variable in Verilog?

I am writing to ask how to declare a global variable in Verilog. What declared by parameter and define keywords are essentially constants, not variables.
What I need is the following:
`define Glitch
module Cell ( Shift_In, Shift_Out_Screwed, Clk );
input Clk, Shift_In;
output Shift_Out_Screwed;
wire Shift_Out_Screwed;
wire Shift_Out;
Inverter INV1 ( Shift_In, Shift_Out, Clk );
assign Shift_Out_Screwed = Glitch ? ~Shift_Out : Shift_Out
endmodule
This is a very simple glitch insertion. When Glitch==1, the original output is reversed; when Glitch==0, the original output is kept unchanged. I want the signal Glitch to be defined in an external simulation testbench.v file although it is declared and used here, and I don't want to add the signal Glitch to the input port list of the module cell. This is because that my real circuit is a very complicated one, and if I add an input port to a certain cell, there will be many other cells affected.
Does anyone know how to declare a global variable in Verilog?
The problem you are wrestling with sounds like error injection. You want the ability to inject a bit error on an output port from within a testbench. You can do it like this:
module Cell ( Shift_In, Shift_Out_Screwed, Clk );
input Clk, Shift_In;
output Shift_Out_Screwed;
wire Shift_Out_Screwed;
wire Shift_Out;
Inverter INV1 ( Shift_In, Shift_Out, Clk );
`ifdef SIMULATION
// This logic is used in simulation, but not synthesis. Use care.
logic Glitch = 1'b0;
assign Shift_Out_Screwed = Glitch ? ~Shift_Out : Shift_Out
`else
// This logic is used in synthesis, but not simulation. Use care.
assign Shift_out_Screwed = Shift_out;
`endif
endmodule
Note that I use the "SIMULATION" preprocessor switch to hide the "Glitch" error injection from synthesis. Use this technique with care to avoid creating simulation/synthesis mismatches.
In your testbench, you can induce a glitch in a specific instance of your cell by referencing the "Glitch" signal in the design hierarchy, like this:
initial begin
...
#(posedge Clk); #1;
$top.u_foo.u_bar.u_cell.Glitch = 1'b1;
#(posedge Clk); #1;
$top.u_foo.u_bar.u_cell.Glitch = 1'b1;
...
end
The above code snippet will inject one cycle of "Glitch".
As an alternative: a more traditional way of injecting errors is to use the "force" statement in the testbench to override a driven in a device under test.

Verilog module for a smoke detector and a buzzer

I have Altera DE2-115 FPGA and I try to self-learn Verilog. I decided to make a smoke detector and whenever it smells smoke the buzzer rings (the smoke detector outputs a digital signal).
Here is my trial :
module fire(flag,clock,reset,fire,fire_state,firealarm);
input clock, reset, flag, fire;
output [2:0] fire_state;
output firealarm;
wire fire;
reg [2:0] fire_state;
assign firealarm = (fire_state == 1) ? (flag ? 0 : 1) : 0;
always # (posedge clock)
fire_state<= fire ? 1: 0;
end module
But it doesn't run and I think there are a lot of logic errors in this code, any help please? :)
endmodule is one word, you need to remove the space.
Almost all simulators these days support verilog-2001 or greater so I would encourage the use of the modern port style (ANSI) and not the old verilog 1995 style.
Your port list goes from:
module fire(flag,clock,reset,fire,fire_state,firealarm);
input clock, reset, flag, fire;
output [2:0] fire_state;
output firealarm; wire fire;reg[2:0] fire_state;
to :
module fire(
input clock,
input reset,
input flag,
input fire,
output reg [2:0] fire_state,
output firealarm
);
I have placed each port on a new line with it direction, this makes it much easier to maintain code, it also make it a lot more readable and therefore minimises the chance of typos in connections.
You have used this syntax a lot (flag?0:1), where you using a boolean to select a boolean there is no need to do this and makes it more difficult to read. If you need to invert it then is a bitwise invert (~). However it is not clear what you are using flag for.
for comparrisons and assignments you should be including the width.
assign firealarm = (fire_state == 3'b1)? (~flag) : 1'b0;
This could also be written out in a combinatorial always block:
always #* begin
if (fire_state==3'b001) begin
firealaram = ~flag;
else begin
firealaram = 1'b0;
end
end
fire is 1 bit, fire_state is 3 bits.
always # (posedge clock) begin
fire_state <= {2'b0, fire};
end

<<module name>> not a task or void function in verilog

I am trying to create a module for carry select adder in verilog. Everything works fine except the following portion where it is causing compilation error.
module csa(a,b,s,cout);
input[15:0] a,b;
output [15:0] s;
output cout;
wire zero_c1, zero_c2,zero_c3,zero_c4,zero_c5;
wire one_c1, one_c2,one_c3,one_c4,one_c5;
wire temp_c1,temp_c2,temp_c3,temp_c4,temp_c5;
wire [15:0] s_zero, s_one;
initial
begin
fork
fa(s[0], temp_c1,a[0],b[0],0);
fa_one(s_zero[1],s_one[1],zero_c1,one_c1,a[1],b[1]);
fa_two(s_zero[3:2],s_one[3:2],zero_c2,one_c2,a[3:2],b[3:2]);
fa_three(s_zero[6:4],s_one[6:4],zero_c3,one_c3,a[6:4],b[6:4]);
fa_four(s_zero[10:7],s_one[10:7],zero_c4,one_c4,a[10:7],b[10:7]);
fa_five(s_zero[15:11],s_one[15:11],zero_c5,one_c5,a[15:11],b[15:11]);
join
end
When I try to compile that it says -
the module "fa", "fa_one" are not a task or void function
I deleted the "initial" statement and now it says -
Syntax error near "fork", expecting "endmodule"
I just want to run the code between join and fork in parallel. I have also confirmed that the module fa, fa_one works fine.
Would appreciate if anyone can help me pointing out what I am doing wrong here. Thanks.
Verilog modules are not run or executed but instantiated, they represent physical blocks of hardware.
Everything is in parallel unless you have made effort to time share pieces of hardware. For example you might write an ALU core, which exists only once but use a program ROM to tell it which instruction to process every clockcycle.
Inside your modules you can have combinatorial code and sequential code.
Combinatorial logic will simulate in 0 time but will actually take some time for values to propagate through when placed on real devices.
If this propagation delay is not thought about and very large blocks of logic are created you will struggle to close timing on synthesis, due to the settling time through the logic being greater than the clock speed either side of the combinatorial logic.
Sequential logic implies that the results are held in flip-flops, which only update on clock edges. This means chains of sequential logic can take many clock cycles for data to propagate.
When pipelining a processor you break individual section up with flip-flops giving each section a full clock cycle for combinatorial propagation, at the expense of taking several clock cycles to calculate a single result.
To correct your example you would just have:
module csa(
input [15:0] a,
input [15:0] b,
output [15:0] s,
output cout
);
wire zero_c1, zero_c2,zero_c3,zero_c4,zero_c5;
wire one_c1, one_c2,one_c3,one_c4,one_c5;
wire temp_c1,temp_c2,temp_c3,temp_c4,temp_c5;
wire [15:0] s_zero, s_one;
fa ufa(s[0], temp_c1,a[0],b[0],0);
fa_one ufa_one(s_zero[1],s_one[1],zero_c1,one_c1,a[1],b[1]);
fa_two ufa_two(s_zero[3:2],s_one[3:2],zero_c2,one_c2,a[3:2],b[3:2]);
fa_three ufa_three(s_zero[6:4],s_one[6:4],zero_c3,one_c3,a[6:4],b[6:4]);
fa_four ufa_four(s_zero[10:7],s_one[10:7],zero_c4,one_c4,a[10:7],b[10:7]);
fa_five ufa_five(s_zero[15:11],s_one[15:11],zero_c5,one_c5,a[15:11],b[15:11]);
endmodule
NB: it is module_name #(parameters) instance_name ( ports );
fork is used to run procedural statements within a module in parallel. Separate module instances always run in parallel.
Child modules are instantiated directly within their parent module, not within an initial, begin, or fork which are used for procedural statements. So you can remove the initial, begin, fork, join, and end, and add an endmodule at the end.

How to declare input and output types in verilog

I have this top module that instantiate two modules:
fillRam fillRam1(
.clk(mclk),
.ramaddrb(ramaddrb),
.romaddrb(romaddrb),
.romoutb(romoutbwire),
.raminb(raminb));
vga vgainst(
.ck(mclk),
.HS(HS),
.VS(VS),
.outRed(OutRed),
.outGreen(OutGreen),
.outBlue(OutBlue),
.sw(sw),
.romouta(romoutawire),
.ramouta(ramoutawire),
.romaddra(romaddra),
.ramaddra(ramaddra));
In this top module, i also have two module that makes the connections on the RAM and ROM.
rom rom_instance (
.clka(mclk), // input clka
.addra(romaddrawire), // input [14 : 0] addra
.douta(romouta), // output [7 : 0] douta
.clkb(ck), // input clkb
.addrb(romaddrbwire), // input [14 : 0] addrb
.doutb(romoutb) // output [7 : 0] doutb
);
The thing i want to do is, get the romaddra value from vga module, give it to rom_instance, and get the romouta value and give it back to vga module back.
I declare two variables for that:
reg [14:0] romaddra;
wire [14:0] romaddrawire;
reg [7:0] romouta;
wire [7:0] romoutawire;
assign romaddrawire = romaddra;
assign romoutawire = romouta;
In every clock cycle, i get the romaddra value from vga instance, write it to romaddrawire and give it to the ROM instance. Then i take the romouta value, write it to romoutawire and give it back to the VGA instance.
I have similar declarations on other rom ports and ram ports. But in all of them i get this error.
ERROR:HDLCompilers:102 - "top.v" line 82 Connection to output port 'romaddra' must be a net lvalue
in vga verilog code:
output reg [14:0] romaddra;
and in rom verilog:
output [7 : 0] douta;
Im very confused about this whole reg and wire types. I would be glad if someone explain what is going wrong here and the reason aswell. Thanks.
If your workflow allows you to use SystemVerilog then these can all become logic instead of reg or wire and your problem goes away.
You can read up more on it later but for now use a wire for connectivity or as part of an assign statement. Use reg when you want to define the value in an always block:
wire a_wire;
wire b_wire;
example_a_module(
.a( a_wire )
);
example_b_module(
.a( a_wire )
);
assign b_wire = ~a_wire ;
Regs
reg a_reg;
reg b_reg;
always #* begin
a_reg = something_else;
end
always #(posedge clk or negedge rst_n) begin
if (~rst_n) begin
b_reg <= 1'b0;
end
else begin
b_reg <= something_else;
end
end
Output ports can be any type, if you hook them up by name (it looks like you have) rather than by order.
Output a is a wire type:
module example_a_module(
output a
);
endmodule
Here b is a 10 bit reg type:
module example_c_module(
output reg [9:0] b
);
endmodule
You can think of regs as sticky, while wires just connect two points (like a physical wire). This doesn't necessarily mean that a reg will always be synthesized to a flip flop, but a reg will hold its previous value until a newer value is assigned. Wires, on the other hand, are memoryless.
Generally speaking, outputs of modules tend to be regs, and the interconnection between modules tend to be wires. This is because the logic for generating the proper output tends to be encapsulated in the module, so the instantiating module can just pass outputs along. Of course, in more complicated systems, this won't hold true where modules will be nested inside modules. But the concept stays the same -- if you're just trying to pass data along from one module to another, use a wire. If you need the data to be "sticky", use a reg.
With all that said, what was the reasoning behind making romaddra a reg and not a wire?
At the top level, just declare bus wires and use those bus wires in the instantiations. Think of reg and assign as drivers, you don't want a driver, you want a wire, hence use 'wire'. When you do 'wire a=1' it's really an assign, which creates a driver. Bottom line, when you want to connect, use only a wire, not an assign or a reg.
wire [14:0] connector_15;
wire [8:0] connector_9;
fillRam fillRam1(
.clk(mclk),
.ramaddrb(ramaddrb),
.romaddrb(romaddrb),
.romoutb(romoutbwire),
.raminb(raminb));
vga vgainst(
.ck(mclk),
.HS(HS),
.VS(VS),
.outRed(OutRed),
.outGreen(OutGreen),
.outBlue(OutBlue),
.sw(sw),
.romouta(connector_9),
.ramouta(ramoutawire),
.romaddra(connector_15),
.ramaddra(ramaddra));
rom rom_instance (
.clka(mclk), // input clka
.addra(connector_15), // input [14 : 0] addra
.douta(connector_9), // output [7 : 0] douta
.clkb(ck), // input clkb
.addrb(romaddrbwire), // input [14 : 0] addrb
.doutb(romoutb) // output [7 : 0] doutb
);