Leaving some bits in the port vector disconnected. Verilog module instantiation - verilog

Lets say I have a Verilog module with bit vector ports. How do I
instantiate it with some bits left unconnected?
I tried something like this but it didn't work:
module sub (in,out)
input [3:0] in;
output [3:0] out;
endmodule
module top;
wire [1:0] a1;
wire [1:0] c1;
sub Sub1(
.in[2:1](a1[1:0]),
.out[2:1](c1[1:0])
);
endomdule

It would be much easier to just declare signals of the correct size and use a continuous assignment
module top;
wire [1:0] a1;
wire [1:0] c1;
wire [3:0] pin;
wire [3:0] pout;
assign pin[2:1] = a1;
assign c1 = pout[2:1];
sub Sub1(
.in(pin),
.out(pout)
);
endomdule
In general, it is not a good idea to leave input ports floating. You could use a concatenation in the assignment, or directly in the port connection.
sub Sub1(
.in({1'b0,a1,1'b0}),
.out({pout[3],c1,pout[0]})
);
SystemVerilog has a net aliasing construct that makes thing even simpler
module top;
wire [3:0] pin;
wire [3:0] pout;
alias pin[2:1] = a1;
alias pout[2:1] = c1;
sub Sub1(
.in(pin),
.out(pout)
);
endomdule

Found LRM reference on why you cannot connect parts of ports.
LRM 1800-2012 Section 23.3.2.2 Connecting module instance ports by name:
The port_name shall be the name specified in the module declaration. The port name cannot be a bit-select, a part-select, or a concatenation of ports.

you cannot connect/disconnect parts of a port. You can do it with the whole port though. so, in your case you nedd to split your port in several parts, something like the following:
module sub (in1, in2, out1, out2);
input [2:1] in1;
input [1:0] in2;
output [2:1] out1;
output [1:0] out2;
endmodule
module top;
wire [1:0] a1;
wire [1:0] c1;
sub Sub1(
.in1(a1[1:0]),
.in2(),
.out1(c1[1:0]),
.out2()
);
endmodule

My code connect 4-bits to module's 8-bit outputs, upper/lower even middle part.
It does work, but what the hell is the 's'(or anything)?
It works in both Quartus Prime 18.0pro and Lattice Diamond 3.10(Symplify Pro).
module dff8
(
input clk,
input [7:0] a,
output reg [7:0] b
);
always # (posedge clk) begin
b <= a;
end
endmodule
module top
(
input clk,
input [7:0] x,
output [3:0] y,
output [3:0] z
);
dff8 u0 (.clk(clk), .a(x), .b({y,s,s,s,s}));
dff8 u1 (.clk(clk), .a(x), .b({s,s,s,s,z}));
endmodule

Related

Facing Some problem is FSM design and datapath [duplicate]

The output waveform shows no change in the sum, dif, burrow, and out. Even after increasing delay time, still the output shows no change. This should work like the mod adder like add 10 and 2 and with mod 3 give output zero.
CODE
module Mod_adder(a,b,p,out);
input [3:0] a;
input [3:0] b;
input [3:0] p;
output [3:0] out;
wire [3:0] sum;
wire cout;
wire burrow;
wire [3:0] dif;
ripple_carry_adder r1(a,b,sum,cout,1'b0);
ripple_carry_adder r2(sum,~p,dif,burrow,1'b1);
repeat_sum rs1(dif,burrow,sum);
outval o1(sum,burrow,out);
endmodule
module full_adder(in0, in1, cin, out, cout);
input in0, in1, cin;
output out, cout;
assign out = in0 ^ in1 ^ cin;
assign cout = ((in0 ^ in1) & cin) | (in0 & in1);
endmodule
module ripple_carry_adder(in0, in1, out, cout,cin);
input [3:0] in0;
input [3:0] in1;
output [3:0] out;
output cout;
input cin;
wire c1, c2, c3;
full_adder fa0(in0[0], in1[0], cin, out[0], c1);
full_adder fa1(in0[1], in1[1], c1, out[1], c2);
full_adder fa2(in0[2], in1[2], c2, out[2], c3);
full_adder fa3(in0[3], in1[3], c3, out[3], cout);
endmodule
module repeat_sum(dif,burrow,sum);
input [3:0] dif;
input burrow;
output [3:0] sum;
assign sum = (burrow == 1'b0) ? dif:sum;
endmodule
module outval(sum,burrow,out);
input [3:0] sum;
input burrow;
output [3:0] out;
assign out = (burrow == 1'b1) ? sum:out;
endmodule
TEST BENCH
` include "MOD_ADDER.V"
module Mod_adder_tb;
reg [3:0] a;
reg [3:0] b;
reg [3:0] p;
wire [3:0] out; // wires
// Instantiate the module to be tested
Mod_adder MA1(a,b,p,out);
initial begin // initial block
$dumpfile("Test_Full_Adder.vcd");
$dumpvars(1, MA1);
a=4'b1010;
b=4'b0100;
p=4'b0011;
#100;
end // end of initial block
endmodule
I see 2 major problems.
Your out testbench signal is unknown (X) because of driver contention. For example, the sum signal in Mod_adder has multiple drivers: from the r1 instance and from the rs1 instance. The out output of r1 and the sum output of rs1 are both driving the sum wire. You should not drive the same signal from 2 different module instances. You could rename one of the sum signals to something unique, like sum_rs1 and declare a new wire.
wire [3:0] sum, sum_rs1;
Also, you have combinational feed back loops. For example:
assign out = (burrow == 1'b1) ? sum:out;
The out signal should not be on both the LHS and RHS of a continuous assignment.

I am getting unknown value when doing a 4 bit shifter verilog (gate level)

I am trying to implement a 4 bit right shifter using gate level but i got unknown result for some reason, my mux work ok but when i try testbench for my shifter it give back something like this:
a=0010 b=01 c=0000
a=1111 b=01 c=00xx
Please help!!!! Thank you very much
module mux2(a,b,sel,c);
output c;
input a,b,sel;
wire net0,net1,net2;
not m1(net0,sel);
and m2(net1,a,net0);
and m3(net2,b,sel);
or m4(c,net1,net2);
endmodule
module mux4(a,sel,c);
output c;
input [1:0]sel;
input[3:0]a;
wire mux_1,mux_2;
mux2 m1(a[3],a[2],sel[0],mux_1);
mux2 m2(a[1],a[0],sel[0],mux_2);
mux2 m3(mux_1,mux_2,sel[1],c);
endmodule
module shift4bitright(c,a,b);
output [3:0]c;
input [3:0]a;
input [1:0]b;
wire [3:0]d=4'h0,d1=4'h0,d2=4'h0,d3=4'h0;
assign d[0]=a[3];
assign d1[0]=a[2]; assign d1[1]=a[3];
assign d2[0]=a[1]; assign d2[1]=a[2]; assign d2[2]=a[3];
assign d3[0]=a[0]; assign d3[1]=a[1];assign d3[2]=a[2];assign d3[3]=a[3];
mux4 m1(d,b,c[3]);
mux4 m2(d1,b,c[2]);
mux4 m3(d2,b,c[1]);
mux4 m4(d3,b,c[0]);
endmodule
`timescale 10ns/1ns
module shift4bitright_tb;
wire [3:0]c;
reg [3:0]a;
reg [1:0]b;
shift4bitright s1(.c(c),.a(a),.b(b));
initial begin
$monitor("a=%b b=%b c=%b",a,b,c);
a=4'h2;
b=2'd1;
#50
a=4'hf;
b=2'd1;
end
endmodule
This statement declared a wire type signal d as well as its driver cone (NOT initial value), which is a constant 0 in this case:
wire [3:0]d=4'h0;
Just below it, there's another a[3] driving d[0]:
assign d[0]=a[3];
This creates a multi-driven logic, hence x occurs.
To solve it, change it similar to:
wire [3:0] d;
assign d = {3'h0, a[3]};

How to switch modules in verilog?

I want to use SW[15] to switch between module A_7seg and B_7seg but it does not work. (2 modules work separately)
module mix(input CLOCK,input [15:0]SW,output reg [15:0] led,output [3:0] an,output reg[7:0] seg);
generate
case(SW[15])
1'b0:A_7seg (.CLOCK(CLOCK),.an(an),.seg(seg));
1'b1:B_7seg (.CLOCK(CLOCK),.SW(SW),.led(led),.an(an),.seg(seg));
endcase
endgenerate
endmodule
Since '2 modules work separately', the simple way is to use SW[15] to select between 2 modules' outputs.
module mix(
input CLOCK,
input [15:0] SW,
output reg [15:0] led,
output reg [3:0] an,
output reg [7:0] seg
);
wire [15:0] B_led;
wire [3:0] A_an, B_an;
wire [7:0] A_seg, B_seg;
// if not using 'generate' block, modules are instantiated at
// the top level, not in other 'if'/'case'/... structures.
// and name the 2 instantiations
A_7seg u_A_7seg (.CLOCK(CLOCK), .an(A_an), .seg(A_seg));
B_7seg u_B_7seg (.CLOCK(CLOCK), .SW(SW), .led(B_led), .an(B_an), .seg(B_seg));
// this extra circuit is needed to select between the two
always#(*)begin
if(SW[15])begin
led = B_led;
an = B_an;
seg = B_seg;
end
else begin
led = 16'h0; // <-- I assume the inactive value for 'led' is all-zero
an = A_an;
seg = A_seg;
end
end
endmodule
You may also want to use SW[15] to gate the inputs to the one that is not currently working to reduce power consumption.
You need to figure out the schematic before you understand how to write the code.

Connect 5-bit bus to 32-bit output bus

My design needs multiple multiplexers, all of them have two inputs and most are 32 bits wide. I started with designing the 32 bit, 2:1 multiplexer.
Now I need a 5 bit, 2:1 multiplexer and I want to reuse my 32 bit design. Connecting the inputs is easy (see code below), but I struggle to connect the output.
This is my code:
reg [4:0] a, b; // Inputs to the multiplexer.
reg select; // Select multiplexer output.
wire [4:0] result; // Output of the multiplexer.
multiplex32_2 mul({27'h0, a}, {27'h0, b}, select, result);
When I run the code through iverilog, I get a warning that says that the multiplexer expects a 32 bit output, but the connected bus is only 5 bit wide. The simulation shows the expected results, but I want to get rid of the warning.
Is there a way to tell iverilog to ignore the 27 unused bits of the multiplexer output or do I have to connect a 32 bit wide bus to the output of the multiplexer?
I don't know of a #pragma or something like that (similar to #pragma argsused from C) that can be used in Verilog.
Xilinx ISE, for example, has a feature called "message filtering", which allows the designer to silence specific warning messages. You find them once, select them, choose to ignore, and subsequent synthesis won't trigger those warnings.
Maybe you can design your multiplexer in a way you don't need to "waste" connections (not actually wasted though, as the synthesizer will prune unused connections from the netlist). A more elegant solution would be to use a parametrized module, and instantiate it with the required width. Something like this:
module mux #(parameter WIDTH=32) (
input wire [WIDTH-1:0] a,
input wire [WIDTH-1:0] b,
input wire sel,
output wire [WIDTH-1:0] o
);
assign o = (sel==1'b0)? a : b;
endmodule
This module has been tested with this simple test bench, which shows you how to instantiate a module with params:
module tb;
reg [31:0] a1,b1;
reg sel;
wire [31:0] o1;
reg [4:0] a2,b2;
wire [4:0] o2;
mux #(32) mux32 (a1,b1,sel,o1);
mux #(5) mux5 (a2,b2,sel,o2);
// Best way to instantiate them:
// mux #(.WIDTH(32)) mux32 (.a(a1),.b(b1),.sel(sel),o(o1));
// mux #(.WIDTH(5)) mux5 (.a(a2),.b(b2),.sel(sel),.o(o2));
initial begin
$dumpfile ("dump.vcd");
$dumpvars (1, tb);
a1 = 32'h01234567;
b1 = 32'h89ABCDEF;
a2 = 5'b11111;
b2 = 5'b00000;
repeat (4) begin
sel = 1'b0;
#10;
sel = 1'b1;
#10;
end
end
endmodule
You can test it yourself using this Eda Playground link:
http://www.edaplayground.com/x/Pkz
I think the problem relates to the output of the multiplexer which is still 5 bits wide. You can solve it by doing something like this:
reg [4:0] a, b; // Inputs to the multiplexer.
reg select; // Select multiplexer output.
wire [31:0] temp;
wire [4:0] result; // Output of the multiplexer.
multiplex32_2 mul({27'h0, a}, {27'h0, b}, select, temp);
assign result = temp[4:0];
This can be easily tested in http://www.edaplayground.com/ using the code below:
( I have re-used #mcleod_ideafix's code)
// Code your testbench here
// or browse Examples
module mux #(parameter WIDTH=32) (
input wire [WIDTH-1:0] a,
input wire [WIDTH-1:0] b,
input wire sel,
output wire [WIDTH-1:0] o
);
assign o = (sel==1'b0)? a : b;
endmodule
module tb;
reg [31:0] a,b;
wire [31:0] o;
wire [4:0] r;
reg sel;
initial begin
$dumpfile("dump.vcd"); $dumpvars;
a = 10; b = 20; sel = 1;
end
mux MM(a,b,sel,o);
assign r = o[4:0];
endmodule
Let me know if you are still getting a warning.

Why are output nets also required to be redeclared as either 'wire' or 'reg'?

Why do we have to take the same variable name of an output and also wire for getting the value? eg:
module TEST(INP1,INP2,CIN,COUT,SUM);
input [31:0] INP1;
input [31:0] INP2;
output [31:0] SUM;
input CIN;
output COUT;
wire [31:0] SUM;// Again redefined
wire COUT; // Again Redefined
assign {COUT,SUM} = INP1 + INP2 + CIN ;
Example for getting the Carry-out and the Sum of two numbers and Carry-In taken as the input.
Verilog 1995 did require the port direction to be listed after. Output wire types were implicit and regs could be declared inline with direction.
module TEST(A,B,C,D);
input [31:0] A;
input [31:0] B;
output [31:0] C;
output D;
reg D;
could be written as:
module TEST(A,B,C,D);
input [31:0] A;
input [31:0] B;
output [31:0] C;
output reg D; //Only declared twice
Since Verilog 2001 the extra definition is no longer required and they can be declared inline (ANSI-Style).
module TEST(
input [31:0] A,
input [31:0] B,
output [31:0] C,
output reg D // Declared Once
);
From SystemVerilog (2009) we have the logic type, you no longer have to switch between reg and wire types. The only requirement is that if you need to tri-state use wire or tri.
module TEST(
input [31:0] A,
input [31:0] B,
output logic [31:0] C,
output logic D
);
My understanding of the original requirement for having reg and wire types was for simulation speed or ease of simulator design. The value of a wire is evaluated every simulation delta cycle while a reg is only evaluated when triggered by the sensitivity list.
It is not necessary to declare an output also as a wire. Furthermore, you can avoid duplicating the port list by using ANSI-stlye port declarations:
module TEST (
input [31:0] INP1,
input [31:0] INP2,
output [31:0] SUM,
input CIN,
output COUT
);
assign {COUT,SUM} = INP1 + INP2 + CIN ;
endmodule
In your example, you do not need to declare outputs as reg. But, if you need to for another circuit, you can declare the type on the same line, such as:
output reg [31:0] Q;
Because just declaring a net as output doesn't describe if it is a reg type or a wire type.
An output can either be driven by a wire or reg, you have to tell it what type the driver is going to be.

Resources