Calling a Module in Verilog - verilog

I just started learning hardware programming using Verilog, and I feel lost because I can't understand what errors mean.
Here, I am calling the module reg31
module nbit_register(input clk, input [31:0]in, input reset, input L,
input load, input shift, output reg[31:0] out);
always#(*)begin
if(load==1)
reg32 add(clk, in, reset,L, out);
else
out={ in[30:0],1'b0};
end
endmodule
But, I get this error:
error: syntax error near "reg32"
This is what the module looks like
module reg32(
input clk,
input [31:0] in,
input rst,
input L,
output [31:0] out
);
Can someone point out the mistake here?

Because you want to "select" and make module reg32 "work" in a if branch.
Imaging a cell phone PCB board. The speaker unit is just out there, even if it's in silent mode. So instantiate reg32 separately, then use your own logic to deal with the nets connected to reg32.
wire [31:0] add_out;
reg32 add(clk, in, reset,L, add_out); // here the 4 inputs are connected to top inputs
// directly. but if you want, you can use 'load'
// to control them similar to the code below.
always#(*)begin
if(load==1)
out = add_out;
else
out = { in[30:0],1'b0};
end
If you're mainly working on software, you need to be familiar to thinking in a "hardware" way.

Related

Declare a port in Verilog where some bits are inputs and some are outputs

In verilog for Cyclone 3 I want to declare a port where some pins are inputs and some are outputs, in many examples in web i see that a port is defined like
input wire [0:10]p;
but what to do if i need bit0 being an input of the IC, while others be an output. Tried like this and some other different variants, but every time i get errors from the compiler. Notice that IO[1] unused in code but present in "Assignment editor".
module main(
tx,
rx,
IO[0],
IO[2]
);
output wire tx;
input wire rx;
input wire IO[0];
output wire IO[2];
assign IO[2] = rx;
assign tx = IO[0];
endmodule
You can use a port_expression. This separates the name of the port from the signals (or expression of signals) connected to the port. You might recognize this syntax when creating a module instance, but it has always been available for a module declaration as well in Verilog
module m(input .rx(a[0]), output .tx(a[1]));
wire [1:0] a;
endmodule
module top;
wire a,b;
m m1(.rx(a),.tx(b));
endmodule
there is no way in verilog to declare different directions to different bits of a single vector port. The direction works on the whole declaration of a port. The only way to do it is to split the single port into multiple ports with different names, e.g.
module main(
output wire tx,
input wire rx,
output wire out,
input wire in
);
Then, when you instantiate it, you can define which bits goes where:
main inst(.tx(tx), .rx(rx), .out(IN[0]), .in(IN[2]);
Since the top level module is not instantiated per se, it doesn't seem using port expressions can work here.
One thing you should try is to change the name of the pins in the pin assignment file (.csv I think) you are loading into Quartus to program your fpga. Give the different pins different names there, e.g. not In[0] or In[1], but rather in0, in1 and so on.

Verilog: proper way of connecting ports

Assume there are two different modules (first_module, second_module). Both of the modules are synchronized with clock signal. first_module has the following structure:
module first_module(
input clk,
input reset_n,
input in1,
output reg out1,
output reg out2
);
//******** some verilog codes *********
endmodule
And second_module has similar structure:
module second_module(
input clk,
input reset_n,
input in1,
input in2,
output reg out1
);
//******** some verilog codes *********
endmodule
And then there is a module called top_module which uses instances of both modules:
module top_module(
input clk,
input reset_n,
input insignal1,
input insignal2,
output outsignal1,
output outsignal2
);
first_module fm1(
.clk(clk),
.reset_n(reset_n),
.in1(insignal1),
.out1(outsignal1),
.out2(<connection1>) // to be connected to the connection2
);
second_module sm1(
.clk(clk),
.reset_n(reset_n),
.in1(insignal2),
.in2(<connection2>), // to be connected to the connection1
.out1(outsignal2)
);
endmodule
The aim is to connect connection1 to connection2. According to my knowledge (if it is correct), we can either declare a single wire (let its name be connection) and replace both <connection1> and <connection2> with it, or we can declare two distinct wires connection1 and connection2, then:
assign connection2 = connection1;
And connect them accordingly.
Are those two methods synthesized differently? If the answer is yes, I would be glad if you could explain how they are synthesized.
If the answer is no, can one of the methods be better than the other in different conditions? Not in terms of lines of code or simplicity, but in terms of synthesis.
Yes there is a difference. But not in your specific case.
Using a connection directly makes that is can be uni-directional or bi-directional depending on what the underlying ports in the module are.
But assign connection2 = connection1; is only uni-directional.
Thus between bi-directional ports should use direct connections or you should only use bi-directional Verilog constructs between them. The assign ... is not one of them.
But in you case the signal is uni-directional so it does not matter.
Note that modern FPGAs no longer have on-chip bi-directional buses. (At least I don't know one that has). Also in chip design on-chip buses are strongly discourage or outright forbidden by the manufacturers.
Therefore bi-directional signals are normally only present in the test-bench. As that does not get synthesized your question does not apply there.
Last but not least:
In HDL design I would strongly discourage from changing the name of a signal for no apparent reason. Having the same name throughout the design makes it easier to debug and trace your signals post-synthesis.

iverilog testbench module with outputs

I'm trying to make a testbench to simulate a working top level module (and child module) however I can't get iverilog to handle the output of top correctly (LEDS,RS232Rx and RS232Tx are physical pins)
here's my attempt at a testbench
module test();
initial begin
$dumpfile("test.vcd");
$dumpvars(0,test);
# 1024 $stop;
end
reg clk = 0; always #1 clk = !clk;
//reg rx,tx;
reg [7:0] opl;
top top1 ( .clk(clk), .RS232Rx(rx), .RS232Tx(tx), .LEDS(opl) );
endmodule
I'm seeing error like this
iverilog -o test-design testbench.v top.v
top.v:47: error: LEDS is not a valid l-value in test.top1.
top.v:8: : LEDS is declared here as wire.
testbench.v:10: error: reg opl; cannot be driven by primitives or continuous assignment.
testbench.v:10: error: Output port expression must support continuous assignment.
testbench.v:10: : Port 4 (LEDS) of top is connected to opl
3 error(s) during elaboration.
I've tried alsorts of things but with not much in the way of an illuminating or different error message, the best LEDS as a testbench output, showing only an error in top.v which is working... I see very similar errors with rx,tx but commented them out to make a shorter output...
just to reiterate top.v does, not only synthesize but behaves exactly as expected on actual hardware
Turns out that despite my top level design was able to output to a wire, iverilog wasn't happy to do this,
adding
reg [7:0] leds;
assign LEDS=leds;
allows my top level design to work on hardware (as before), but also iverilog (icarus) now seems able to deal with it...

In verilog I have an error that I can't get past

module data_path(
input clk,
input rst,
input inc_pc,
input load_mar,
input load_mbr,
input load_ir,
input r_w,
input [7:0] data_in,
input load_ac,
input mux_sel,
output [7:0] ir_out);
reg [3:0]var;
reg [2:0]opcode;
wire [3:0] w1,w2,w6;
wire [7:0] w3,w4,w5;
pc pc1(.rst(rst),.clk(clk),.inc_pc(inc_pc),.pc_out(w1));
register1 mar(.rst(rst),.clk(clk),.load(load_mar),.in(w1),.out(w2));
memory memory1(.add_in(w2),.data_in(data_in),.data_out(w3),.r_w(r_w));
register2 mbr(.rst(rst),.clk(clk),.load(load_mbr),.in(w3),.out(w4));
register1 ir(.rst(rst),.clk(clk),.load(load_ir),.in(w4),.out(w5));
assign opcode=w4[7:5];
if(opcode==3'b000)
register1 ac(.rst(rst),.clk(clk),.load(load_ac),.in(w4[4:0]),.out(w6));
else
if(opcode==3'b001)
begin
assign var=w6+w4[4:0];
register1 ac(.rst(rst),.clk(clk),.load(load_ac),.in(var),.out(w6));
end
endmodule
Getting error:
data_path.v line 52 expecting 'endmodule', found 'if'
if usually used in the always or initial block (Procedural Blocks; so you can't check opcode with if outside of procedural block. Try to move if inside always # (posedge clk).
You also should move register1 ac(.rst(rst),.clk(clk),.load(load_ac),.in(w4[4:0]),.out(w6)); instantiation outside of if, because you describe hardware and there is no Conditional instantiation of verilog modules
If 'register1' is another Verilog module, this logic will not work. In your code, you are using the output of a Verilog module (something that is not known at static-run time but that instead my change every clock cycle) to determine which of two instances to instantiate.
Instances will exist from the start of run time, and cannot be brought in and out of existence every clock cycle. Instead, you will have to create both instances of 'register1 ac' as two separate instances (with different names, and with their outputs named differently). And then use a mux (multiplexor) to select between the two output busses depending on the value of 'opcode'.
Both prior answers correctly capture some information. You're trying to mux an input to register1 based on the opcode. A little weirdness in that you're sending in either 4b or 5b based on the if-else. I'll let it slide and assume 5b without sign extension for now. Also your output is 4b.
One other thing. Overflow in the opcode 3'b001 add (which doesn't add up in your assign) - how would one add 4b(w6) + 5b(w4[4:0]) into 4b (var) reliably?
Here's the (untested, caution) code revision (snippet of your code above).
Declare a wire that you mux per the opcode.
wire [7:0] tmpin;
Now correctly write the always to capture the behavior
always #(*) begin
if(opcode==3'b000) tmpin = {3'b0,w4[4:0]};
elsif (opcode == 3'b001) tmpin = {4'b0,w6} + w4;
end
Then you just follow with the muxed variable into a concurrent statement - the register declaration.
register1 ac(.rst(rst),.clk(clk),.load(load_ac),.in(tmpin[4:0]),.out(w6));
Have fun!

Verilog Input to Wire

I am trying to make a clock in verilog on my Altera DE2 board. As of now I can count from 00:00:00 to 23:59:59 using flipflops as a clock. Now I need to be able to set Switches to some value, say 12:56:00 then have it count up from there. I am trying to set a wire variable to be the initial switches input then use that as a starting point for my counter.
module part3(HEX0,HEX1,HEX2,HEX3,HEX4,HEX5,HEX6,HEX7,SW,KEY,LEDR,CLOCK_50);
input [17:0] LEDR, SW;
input [3:0] KEY;
input CLOCK_50;
output [0:6] HEX0,HEX1,HEX2,HEX3,HEX4,HEX5,HEX6,HEX7;
parameter clock_speed = 50000000;
parameter clock_divisor = 8;
wire [26:0] Q,Q2,Q3,Q4;
wire [3:0] one,two,three,four;
reg SecInc,MinInc,HrInc;
one = SW[3:0];
This is my code up to where it crashes. I do not understand why
wire in = SW[0];
is legal but assigning it the way I have done it not legal. I need to store the switch input in a register or a wire so I can increment that register or wire based on a condition.
Note: I have no formal intro to verilog, our prof gave us a board and a link to the altera university program labs and said have fun.
You need to use the assign keyword. Change:
one = SW[3:0];
to:
assign one = SW[3:0];
That is known as a continuous assignment in Verilog. You don't need the assign keyword if you are making a procedural assignment (inside an always block, for example).

Resources