Can I not pass all the parameters while calling a module which is inside another module? - verilog

//For eg.,the code goes like this
module SR_Latch(input S, input R, output Q1, output Q1b);
begin
wire Q_int, Q_intb;
Q_int = ~(S & Q_intb);
Q_intb = ~(R & Q_int);
Q1 = Q_int;
Q1b = Q_intb;
end
endmodule
module D_latch(input D, input G, output Q, output Qn);
begin
wire R1, R2;
R1 = ~(D & G);
R2 = ~(G & (~D));
//Calling another module which I have already coded
SR_Latch SR_Latch1(.S(R1), .R(R2)); // I am only passing the inputs here. Is this possible?
end
endmodule
I haven't simulated this yet as my university license got expired. I need someone's guidance to learn Verilog as I have previously coded only in a very basic level.

Related

Verilog waveform of inputs is identical, however, output is different

I'm currently trying to implement an up/down counter in Verilog with dataflow modeling. While trying to add a limit to the counter (so that the counter will reset to the appropriate value when the limit is reached) I stumbled into an error. Even though the waveforms of clear_q, clear, and clear_s are the same, likewise the waveforms of preset_q, preset, and preset_s are the same, the behaviors of Q, R, and S are different, notably Q is different from R and S.
Picture of Waveforms
Of note, the rising edge of the three clear signals is not aligned with the falling edge of the clock, however, Q going from 0 to F is aligned with the rising edge of the three clear signals.
From the code, it is clear that the only difference between clear_q and clear_s, and preset_q and preset_s, is the simple inclusion of "& 1'b1". The only way that Q would go to F from 0 is if preset_q goes low and clear_q goes high momentarily, however from the waveform preset_q stays high.
The purpose of the "& 1'b1" is to temporarily simulate the equality checker commented out.
What exactly is wrong with the "& 1'b1" or is there another issue at hand?
limited_ud_counter.v
module limited_ud_counter(input clk, preset, clear, up, input[3:0] limit, output[3:0] Q);
//wire[3:0] n;
wire[3:0] Q, R, S;
wire e, preset_p, clear_p;
// assign n[0] = Q[0] ^ limit[0];
// assign n[1] = Q[1] ^ limit[1];
// assign n[2] = Q[2] ^ limit[2];
// assign n[3] = Q[3] ^ limit[3];
// assign e = !(n[0] | n[1] | n[2] | n[3]);
assign e = 0;
//(preset & clear & (!(e & up))) | (preset & !clear);
//(preset & clear & !(e & (!up))) | (clear & !preset);
assign preset_q = ((preset & clear) & 1'b1) | (preset & !clear);
assign clear_q = ((preset & clear) & 1'b1) | (clear & !preset);
assign preset_s = ((preset & clear)) | (preset & !clear);
assign clear_s = ((preset & clear)) | (clear & !preset);
//Q not showing expected behavior
up_down_counter udc0(clk, preset_q, clear_q, up, Q);
//R showing expected behavior
up_down_counter udc1(clk, preset, clear, up, R);
//S also showing expected behavior
up_down_counter udc2(clk, preset_s, clear_s, up, S);
endmodule;
up_down_counter.v
module up_down_counter(input clk, preset, clear, up, output[3:0] Q);
wire[2:0] jk_up, jk_down, jk;
wire[3:0] Q_bar;
assign jk_up[0] = Q[0] & up;
assign jk_down[0] = Q_bar[0] & (!up);
assign jk[0] = jk_up[0] | jk_down[0];
assign jk_up[1] = Q[1] & jk_up[0];
assign jk_down[1] = Q_bar[1] & jk_down[0];
assign jk[1] = jk_up[1] | jk_down[1];
assign jk_up[2] = Q[2] & jk_up[1];
assign jk_down[2] = Q_bar[2] & jk_down[1];
assign jk[2] = jk_up[2] | jk_down[2];
jkff jkff0(clk, 1'b1, 1'b1, preset, clear, Q[0], Q_bar[0]);
jkff jkff1(clk, jk[0], jk[0], preset, clear, Q[1], Q_bar[1]);
jkff jkff2(clk, jk[1], jk[1], preset, clear, Q[2], Q_bar[2]);
jkff jkff3(clk, jk[2], jk[2], preset, clear, Q[3], Q_bar[3]);
endmodule
jkff.v
module jkff(input clk, j, k, preset, clear, output q, q_bar);
wire j_p, k_p, q_m, q_bar_m;
assign j_p = !(j & q_bar & clk);
assign k_p = !(k & q & clk);
sr sr0(j_p, k_p, preset, clear, q_m, q_bar_m);
gated_sr gsr0(!clk, q_m, q_bar_m, preset, clear, q, q_bar);
endmodule;
sr.v
//set, reset, preset, clear are active low
module sr(input set, reset, preset, clear, output q, q_bar);
assign q = !(set & preset & q_bar);
assign q_bar = !(reset & clear & q);
endmodule
gated_sr.v
//enable, set, and reset are active high; preset and clear are active low
module gated_sr(input enable, set, reset, preset, clear, output q, q_bar);
wire set_p, reset_p;
assign set_p = !(set & enable);
assign reset_p = !(reset & enable);
sr sr0 (
.set (set_p),
.reset (reset_p),
.preset (preset),
.clear (clear),
.q (q),
.q_bar (q_bar)
);
endmodule
testbench code
`include "limited_ud_counter.v"
`include "../UpDownCounter/up_down_counter.v"
`include "../JKFF/jkff.v"
`include "../GatedSR/gated_sr.v"
`include "../SR/sr.v"
module limited_ud_counter_tb;
reg clk, preset, clear, up;
reg[3:0] limit;
wire[3:0] Q;
always begin
#5 clk = !clk;
end
initial begin
$dumpfile("limited_ud_counter_tb.vcd");
$dumpvars;
clk = 1'b0;
up = 1'b1;
preset = 1'b1;
clear = 1'b0;
limit = 4'b1100;
#12 clear = 1'b1;
#200 $finish;
end
limited_ud_counter ludc0(clk, preset, clear, up, limit, Q);
endmodule
This is using Icarus Verilog if that helps.
I've figured out the issue. What was happening was while the values of preset_q and clear_q were being computed, there was a moment where both preset_q and clear_q went low. Since these were fed into SR-latches, an error would occur.
All at the same time (t=12), preset_q and clear_q went like this:
preset_q = 1, clear_q = 0
preset_q = 0, clear_q = 0 <- this is the problem
preset_q = 1, clear_q = 1
Since these all happened at the same time, only the final values were visible on the waveform. To fix this, I chose to make both preset and clear signals go high if they were both low at the SR-latch level.

ALU in Verilog: "Unable to bind wire/reg/memory"

I am trying to make a simple 32 bit ALU with an overflow flag, and then output the inputs and results of the ALU to the screen, but I encountered some problems with connecting the elements for the test bench. I got this error:
test_32bALU.v:15: error: Wrong number of ports. Expecting 4, got 5.
test_32bALU.v:33: error: Unable to bind wire/reg/memory
test_unit.overflow' inalu_test'
2 error(s) during elaboration.
I am just starting with Verilog and I have a basic idea of the syntax. I know I am not supposed to ask debugging questions, but this is my only hope. My professor or TA wouldn't respond to me requests for help. I would appreciate it if anyone here could help me point out my mistakes.
This is my 32bALU.v file:
module alu(
input signed[31:0] a,b,
input[3:0] opcode;
output signed[31:0] c;
output overflow;
);
reg signed[31:0] result;
assign c = result;
reg tmp;
parameter
add = 4'b0000,
sub = 4'b0110,
sla = 4'b0001,
srai = 4'b0011;
always #(a,b,opcode)
begin
case(opcode)
add:
begin
c = a + b;
end
endcase
end
always #(c)
begin
if (c[32:31] == (2'b11 | 2'b10)) // Overflow
begin
tmp = 1'b1;
assign overflow = tmp;
end
else begin
tmp = 1'b0;
assign overflow = tmp;
end
end
assign result = c[31:0];
endmodule
test_32bALU.v
`timescale 1ns/1ps
module alu_test;
// Inputs
reg[31:0] a,b;
reg[2:0] opcode;
// Outputs
wire[31:0] c;
//wire [1:0] zero;
wire [1:0] overflow;
//wire [1:0] neg;
alu test_unit(
a,b, // Inputs
opcode,
c,
overflow
);
parameter
add = 4'b0000,
sub = 4'b0110,
sla = 4'b0001,
srai = 4'b0011;
initial begin
$display("op: a : b : c : reg_A : reg_B : reg_C");
$monitor(" %h:%h:%h:%h:%h:%h:%h",
opcode, a, b, c, test_unit.a, test_unit.b, test_unit.c);
$monitor("%h", test_unit.overflow);
//// add
#10 a=32'b0000_0000_0000_0000_0000_0000_0000_0001;
#10 b=32'b0000_0000_0000_0000_0000_0000_0000_0001;
opcode= add;//3'b000
#10 $finish;
end
endmodule
I am confused as to why it says "wrong number of ports"? I assume it's the number of parameters in module alu and alu test_unit? They have the same number of parameters (a, b, c, opcode and overflow), so what exactly am I missing? How exactly do I get the value of overflow? It works fine before I added the overflow parameter, so I assume I'm doing it wrong?
For the second error, I read somewhere on here that it might be due to a missing declaration, but I have declared all of them... so I am not sure what's making it wrong.
I am not sure if this is the issue, but your module definition is not correct. It should be as follows:
module alu(
input signed[31:0] a,b,
input[3:0] opcode,
output signed[31:0] c,
output overflow
);
Perhaps this may help with your issue.
Commas separate inputs and outputs in the module declaration.
NEVER rely on the order of arguments to modules and ALWAYS try to use, for a module called A;
module A(output wire c,
input wire a,
input wire b);
...
endmodule // A
use an instance of it using;
A yourAname(.c(Bar),
.a(Foo1),
.b(Foo2));
so that if the definition and order of the I/O of the module changes, this instantiation will track those changes and/or give appropriate errors when simulated/synethesised.
You might find it useful to follow a few simple rules in your source code when naming;
inputs are denoted by i_yourinputname
outputs are denoted by o_youroutputname
inout are denoted by io_yourinputoutputname
wire are denoted by w_yourwirename
reg are denoted by r_yourregname
as this avoid confusion and is a good habit to get into as soon as possible when starting to learn verilog.

Problem with Verilog Dataflow testbench causing different errors on different sites

This program is in Dataflow Verilog. What I'm trying to do is make an adder and subtractor dependent on a selector. I am currently getting some errors that are either "syntax error in continuous assignment" for line 10, (the assign {cout...},) or "Error launching EPWave: [Could not parse file: $timescale not found in the header.]. Could not load './dataflow_hw_1.vcd'".
I have looked all over the internet in search of how to solve this problem, but I keep attempting the recommended solutions to no avail. I don't know what's wrong when trying to testbench it.
Here is the code:
module dataflow_1 (a[7:0],b[7:0],out[7:0],cout);
input a,b;
output out,cout;
//if a have odd number of 1s, output = a + b
//else if even positions have even number of 1s in total, output = a-b
assign selectorOdd = (a[1]^ a[3]^ a[5] ^ a[7]);
assign selectorEven = (~selectorOdd & ~(a[0] ^ a[2] ^ a[4] ^ a[6]));
assign {cout,out[7:0]} = (selectorOdd & ({a[7:0] + b[7:0}) | (selectorEven & ({a[7:0] - b[7:0]}));
endmodule
Here is the testbench code:
// Code your testbench here
module dataflow_1();
reg [7:0] a;
reg [7:0] b;
wire [7:0] out;
dataflow_1 test(
.a(a),
.b(b),
.out(out)
);
initial begin
$dumpfile("dump.vcd");
$dumpvars(0, out);
a = 8'b01010101;
b = 8'b00000001;
#100;
end
endmodule
The problem is on this line:
assign {cout,out[7:0]} = (selectorOdd & ({a[7:0] + b[7:0}) | (selectorEven & ({a[7:0] - b[7:0]}));
you used wrong {} and [], {} used to concatenate the bits. It should be fixed like this:
assign {cout,out} = selectorOdd ? (a + b) : (selectorEven ? (a - b) : {9{1'b0}});
Your code should have more the case for else all. In this code if selectorOdd and selectorEven are 0, I assign {cout,out}={9{1'b0}}.

Memory code errors in Verilog

I write Verilog program to simulate memory transfer to Temp , but i got a lot of errors, help please.
wire [64:0] temp,mem [0:256];
wire [15:0] w0, w1, w2, w3;
wire [7:0] block_nr;
integer i ;
for ( i=0; i <3; i = i + 1) begin
temp = mem [i];
data_mem [i] = {block_nr, w0,w1, w2, w3 };
block_nr = block_nr +1;
end
5There are many errors in your code. Here are some:
a) Instead of this:
wire [64:0] temp,mem [0:256];
perhaps you mean this?
wire [64:0] mem [0:256]; // this might be a reg, too, one cannot tell from your code snippet
reg [64:0] temp;
i) I don't think you meant temp to be a 65x257 array as well as mem? And did you mean "64"? Or "63"? Or (see below) "71"? And did you mean "256"? Or "255"?
ii) You cannot assign to a wire from inside a procedural block.
b) This needs to be a reg, too, because (again) you cannot assign to a wire from inside a procedural block.
reg [7:0] block_nr;
c) This code needs to go inside a procedural block, either initial or always. Which depends on your design intent - I cannot tell this from your snippet of code. Let's assume initial:
initial begin
for ( i=0; i <3; i = i + 1) begin
temp = mem [i];
data_mem [i] = {block_nr, w0,w1, w2, w3 }; // what is "data_mem"? Did you mean "mem"?
// if you did mean "mem", did you notice that "{block_nr, w0,w1, w2, w3 }" is 72 bits wide?
block_nr = block_nr +1;
end
end
If this is intended to be synthesised, the you cannot use initial. If you do intend to synthesise this, you are a long way from a working solution.
I must emphasise, however, that these are merely suggestions. It is not possible to completely correct errors in code whose design intent is not known.

Using created ALU to make a bigger one

I have a 8-bit ALU unit in verilog that can do addition, invert, etc. This single unit is tested and performs correctly. When I combine 4 of these to make a bigger ALU every output is correct except when I choose the addition operation it comes out as
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01010101, basically the first alu does the work right then the output from the second is xxxxxxxx as is the third and fourth. This is really frustrating!!
the 8 bit module( it would be nice to point if this model is behavioral or structural model i go for the former!)
module alu_8bit(
output reg [7:0] out,
output reg cout,g,e,
input [7:0] A,B,
input cin,
input [2:0] S
);
//used functions
parameter BUF_A = 3'b000;
parameter NOT_A = 3'b001;
parameter ADD = 3'b010;
parameter OR = 3'b011;
parameter AND = 3'b100;
parameter NOT_B = 3'b101;
parameter BUF_B = 3'b110;
parameter LOW = 3'b111;
always #(A or B or S) begin
//Comparator
g = A>B;
e = A==B;
//Other selective functions
case(S)
BUF_A: out = A;
NOT_A: out = ~A;
ADD: {cout,out} = A+B+cin;
OR: out = A | B;
AND: out = A & B;
NOT_B: out = ~B;
BUF_B: out = B;
LOW: out = {8{1'b0}};
endcase
end
endmodule
Here is the code of the bigger one:
module alu_32bit(
output [31:0] out,
output cout,g,e,
input [31:0] A,B,
input cin,
input [2:0] S
);
wire e1,e2,e3,e4;
wire g1,g2,g3,g4;
alu_8bit ALU1(out[7:0],cin2,g1,e1,A[7:0],B[7:0],cin,S);
alu_8bit ALU2(out[15:8],cin3,g2,e2,A[15:8],B[15:8],cin2,S);
alu_8bit ALU3(out[23:16],cin4,g3,e3,A[23:16],B[23:16],cin3,S);
alu_8bit ALU4(out[31:24],cout,g4,e4,A[31:24],B[31:24],cin4,S);
assign g = g4 | (e4 & g3) |(e4 & e3 & g2) | (e4& e3 & e2 & g1);
assign e = e4 & e3 & e2 & e1;
endmodule
Can any one give some help?! if you need more info just tell me.
Edited:
Waveform pic clearly input comes in correct but output not
The dataflow diagram shows that ALU1 output is just fine
Your sensitivity list for the main part of the ALU doesn't include cin.

Resources