Avoiding code repetition in Verilog - verilog

I find that this happens too often in Verilog code:
wire my_module_output_1;
wire my_module_output_2;
wire my_module_output_3;
...
MyModule my_module(
.output_1(my_module_output_1),
.output_2(my_module_output_2),
.output_3(my_module_output_3),
...
);
MyOtherModule my_other_module(
.input_1(my_module_output_1),
.input_2(my_module_output_2),
.input_3(my_module_output_3),
...
);
What I wish I could do is:
MyModule my_module();
MyOtherModule my_other_module(
.input_1(my_module.output_1),
.input_2(my_module.output_2),
.input_3(my_module.output_3),
...
);
Is there any such way for me to achieve the same effect, i.e. to avoid having to repeat myself over and over again every time I need an output from some module wired somewhere?

Here are a few approaches you can use to reduce the amount of repetition.
The starting point
Here's a simple example that connects two sub-modules. As you noted in your question, there is a lot of repetition required to stitch them together.
module source(output A, output B);
assign A = 0;
assign B = 1;
endmodule
module sink(input A, input B);
initial begin
#1 $display("A=%0d B=%0d", A, B);
end
endmodule
module top();
wire A;
wire B;
source the_source(
.A(A),
.B(B)
);
sink the_sink(
.A(A),
.B(B)
);
endmodule
Using implicit wires
Verilog allows for wires to be declared implicitly. So, as shown below, you don't need to declare A and B as wires. If they appear in a port map, they will be implicitly declared. The only problem with this is that they are always declared as single-bit wires/nets. So while this works fine for single-bit signals, for buses the interconnect still needs to be explicitly declared.
// Verilog, implicit wires
module top();
source the_source(
.A(A),
.B(B)
);
sink the_sink(
.A(A),
.B(B)
);
endmodule
Using Verilog-Mode AUTOs
The Verilog-Mode emacs package can help tremendously in reducing the amount of typing required to stitch modules together. Here is the example from above using AUTOs.
Before expanding the AUTOs:
// Verilog, explicit connections using AUTOs
module top();
/*AUTOWIRE*/
source the_source (/*AUTOINST*/);
sink the_sink (/*AUTOINST*/);
endmodule
After expanding the AUTOs:
// Verilog, explicit using AUTOs
module top();
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire A; // From the_source of source.v
wire B; // From the_source of source.v
// End of automatics
source the_source (/*AUTOINST*/
// Outputs
.A (A),
.B (B));
sink the_sink (/*AUTOINST*/
// Inputs
.A (A),
.B (B));
endmodule
As Brian pointed out in his answer, you don't need to use emacs to use Verilog-Mode. I also use Vim and use this Vim script to enable Verilog-Mode from within Vim.
SystemVerilog option
If you can use SystemVerilog, you can use the dot-star notation to connect ports by names. This is pretty handy but you still have to declare the wires for interconnects between peer modules.
// SystemVerilog, dot-star notation
module top();
wire A;
wire B;
source the_source(.*);
sink the_sink(.*);
endmodule

Are people still not using Verilog AUTOs everywhere?
http://www.veripool.org/wiki/verilog-mode/Verilog-mode-Help
In particular pay attention to the section on AUTOINST. This isn't going to solve all your problems but judicious use of AUTOs takes a lot of the tedium out of generating structural Verilog.
Don't mind that it's an Emacs node. I'm a vim guy myself but I just pipe my buffer through emacs with this mode loaded when I need my AUTOs updated.

Related

Calling a Module in 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.

Drive internal signals in verilog from system verilog testbench

How can you drive internal signals of a DUT verilog code from testbench?
Consider this following example:
module dut(input bit clk);
logic [7:0] data;
endmodule : dut
module top;
bit clk;
dut dut1(.*);
assign dut.data = '0; // this doesn't work.
endmodule
Cross module references do work. The catch, though, is that any signal in the DUT will already be driven. You need to override that driver. Force and release are the usual way of doing this but you can also just use a stronger driver strength.
The default drive strength is "Strong" so the only thing stronger is "supply".
For your example:
assign (supply0, supply1) data = '0;
Strictly speaking, the supply1 is unnecessary as you are only driving zero. However, it eliminates the surprise you might get if you ever need to change your code to drive '1'.

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.

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!

Resources