Verilog 4 bit multiplier? - verilog

I'm having problems on how to create a test module for the following Verilog code:
module Multiplier_4bit(output [8:0] y, input [3:0] i1, input [3:0] i2);
assign y=i1*i2;
endmodule
I thought of the following test module:
module M4_Tester
reg [3:0] i1;
reg [3:0] i2;
wire [9:0] y;
initial begin
i1=5;
i2=3;
$finish();
Multiplier_4bit device1(
.out(y),
.in0(i1),
.in1(i2)
);
endmodule
Please correct me if I'm wrong and sorry for bad english, as I am not a native speaker.
Thanks in advance.

You cannot instantiate a module inside of a begin block (put the multiplier somewhere outside of your initial begin block.
You have no corresponding end which closes the initial begin block.
Your simulation will terminate instantly because there is no delay between setting the values and the $finish. Put some nominal time delay before the simulation finishes with #10 $finish().
Next time please clarify your question before asking, and post the actual error messages you are receiving.

Related

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]};

adding two values task in verilog

I am a student and new to verilog. I understand what these codes mean and they seem to be working for me. However, I am having troubles with the task.
module add_two_values_task(output reg sum,output reg cout, input ain,input bin);
task add_two_values;
output [3:0] sum;
output out;
input [3:0]ain;
input [3:0]bin;
reg [3:0] sum;
reg out;
{out, sum} = ain + bin;
endtask
always #(ain or bin) begin
add_two_values(cout,sum,ain,bin);
end
endmodule
However, when I run my simulation:
When I run the simulation, I suppose to get a value for z, however, I ended up with getting letter 'z' for the sum. Did I write my code wrong?
You just forgot about few very important syntax elements. And messed the order of arguments in your task.
module add_two_values_task(output reg [3:0] sum,output reg cout, input [3:0] ain, input [3:0] bin); // You need to declare signals width
task add_two_values;
output [3:0] sum;
output out;
input [3:0]ain;
input [3:0]bin;
reg [3:0] sum;
reg out;
{out, sum} = ain + bin;
endtask
always #(ain or bin) begin
add_two_values(sum,cout,ain,bin); // You messed order of arguments here
end
endmodule
Firstly in module declaration you need to declare bit width of input and output signals (otherwise signals will be assumed length of 1 bit). Secondly in your task call you messed order of arguments. Should work now.

ERROR: 'Checker 'xor_module_b' not found. Instantiation 'x0_1' must be of a visible checker.'?

What is this error 'Checker 'xor_module_b' not found. Instantiation 'x0_1' must be of a visible checker.'? I am writing verilog code in behavioral model by using module instantiation. While compiling i am getting the error. Portion of code and error is attached.
module CSSA4_4bit_modified_b(s,cin,g,G,GP,a,b);
input cin,g,G,GP;
input [7:0] a,b;
output wire [7:0] s;
wire [6:0] c0;
wire [3:0] c1;
wire [2:0] pro;
wire [7:0] s0;
wire [3:0] s1;
always#(a,b,cin,g,G,GP)
begin
//Subblock 1
//Sum bit 0
xor_module_b x0_1(.a(a[0]), .b(b[0]),.s0(s0[0]));
xor_module_b x0_2(.a(s0[0]),.b(cin), .s0(s[0]));
and_logic_b a0 (.a(s0[0]), .b(cin), .out(pro[0]));
//end
//Sum bit 1
FA_b FA_b1(.a(a[1]), .b(b[1]), .c(g),.sum(s0[1]),.cout(c0[0]));
xor_module_b x1 (.a(s0[1]),.b(pro[0]),.s0(s[1]));
and_logic_b a1 (.a(s0[1]),.b(pro[0]), .out(pro[1]));
//end
//Sum bit 2
FA_b FA_b2(.a(a[2]), .b(b[2]), .c(c0[0]),.sum(s0[2]),.cout(c0[1]));
xor_module_b x2 (.a(s0[2]),.b(pro[1]),.s0(s[2]));
and_logic_b a2 (.a(s0[2]),.b(pro[1]),.out(pro[2]));
//end.......continued
//Sum bit 7
FA_b FA_b1_7_1(.a(a[7]),.b(b[7]),.c(c0[5]), .sum(s0[7]),.cout(c0[6]));
FA_b FA_b1_7_2(.a(a[7]),.b(b[7]),.c(c1[2]), .sum(s1[3]),.cout(c1[3]));
sum_select_mux_b M1_7(.Sum(s[7]),.Sum0(s0[7]),.Sum1(s1[3]),.C8k(cin));
//End of subblock 2
//End of CSSA 4-4 bit
end
endmodule
Error Snapshot
You can not instance a module inside an always.
Remove the always#(a,b,cin,g,G,GP)
You don't need the always here but in case you DO need it:
Listing your variable in the always is dangerous. If you forget one you are likely to get mismatches between simulation and reality (gates). Better to let the compiler work it out by using: always #( * )
You can use it in test benches but I can't remember ever needing it.

viewing waveform- Active hdl

I am quite new to verilog and active-hdl. I have got a problem and I would appreciate it if someone could advise me on this.
I can't see the waveforms of second layer modules on waveform viewer. More precisely, the signals in submodules show either Z or X.
Please note that I have enabled read/write access through tools/preferences/simulation/ access design object.
For example I am generating a clk in tb module and connect it to clk_mod, trying to see the clk in clk_mod, however for clk it shows only "Z" and for "i" only "X".
`timescale 1ns/100ps
module tb;
reg clk;
clk_mod dut(.clk(clk));
initial
begin
clk = 0;
forever
#5 clk = ~clk;
end
endmodule
module clk_mod (input clk);
reg i;
always #(posedge clk)
begin
i=10;
end
endmodule
I think that your tb is lacking exit from simulation. you should add the following statement to the tb module (as a separate statement):
initial #20 $finish;
This would finish simulation at step 20 and should create waveforms for you, if you use right tools.
Also, you declared i as a single-bit reg, so, you cannot fit '10' in to it. So, your waveform should show toggling clock and a single transaction of 'i' from 'x' to '0'.
I guess you should have declared 'i' as this:
reg [3:0] i;

Optimizing the registerfile code in systemverilog

I am implementing a 32bit RegFile(containing 32 registers). Now, for the combinational part, I am planning to use the switch case to out the read value of the 32registers based on the input register number. This is resulting in a switch case with 32cases and a default case. Is there any other way to optimize the code? Constraint is that my output needs to be a register and hence I am unable to use the following statement(containing assign):
assign rdDataA = rdAddrA == 0 ? reg0
Code:
module RegFile(input [4:0] src_rd_1,
input [4:0] src_rd_2,
input [4:0] des_wr_1,
input [31:0] data,
input clk,
input reset,
input wr_en,
output reg rd_val_1,
output reg rd_val_2
);
reg [31:0] register[31:0];
always_comb begin
case(src_rd_1)
5'd0:begin
rd_val_1=register[0];
end
5'd1:begin
rd_val_1=register[1];
end
5'd2:begin
rd_val_1=register[2];
end
5'd3:begin
rd_val_1=register[3];
end
5'd4:begin
rd_val_1=register[4];
//and so on...
end
Update:
I found out a way to optimize the code. I hope this would work...Any other suggestions are welcome
if(src_rd_1>=0)
begin
if(src_rd_1==0)
begin
rd_val_1=32'd0;
end
else
begin
rd_val_1=register[src_rd_1];
end
end
Any advise will helpful. TIA
The following is allowed by simulation tools:
always_comb begin
rd_val_1 = register[src_rd_1];
end
You'll have to try it out and see if your synthesis tool supports this.
Using reg doesn't mean it will synthesize to a register. To synthesize to a register a reg (or for SystemVerilogpreferablylogic`) should be assigned in a sequential always block.
always_ff #(posedge clk) begin
rd_val_1 <= register[src_rd_1];
end
Flopping the output makes it a clean, glitch-free output and doesn't add to the combinational propagation delay to any receiving modules.

Resources