Why is it giving error in module part1? - verilog

In my previous question I said that I was asked to design a bottling system that fills bottles with the desired number of tablets. In part1 of my project, the user will press the button on FPGA to identify how many tablets will be put in the each bottle and the desired number will be displayed.This is the code of part 1 I have written for my project and I have no idea why it is giving errors in module part1.
module count(clk,clr,cntEn,dout);
input clk,clr,cntEn;
output reg [8:0] dout ;
always#(posedge clk)
begin
if(clr)
dout<=0;
else if(cntEn)
dout<=dout+1;
end
endmodule
module sevenseg(num,dout);
input [3:0] num;
output reg [6:0] dout;
always#(*) begin
case(num)
0:dout=7'b1111110;
1:dout=7'b1100000;
2:dout=7'b1011011;
3:dout=7'b1001111;
4:dout=7'b1100110;
5:dout=7'b1101101;
6:dout=7'b1111101;
7:dout=7'b0000111;
8:dout=7'b1111111;
9:dout=7'b1101111;
endcase
end
endmodule
module part1(clk,clr,cntEn,dout);
input clk, clr, cntEn;
output dout;
wire w1;
begin
count count_1 (clk, clr, cntEn, w1);
sevenseg sevenseg_1(w1, dout );
end
endmodule

The error was pointed out byljk07, the begin end in module 1 are not required, some parsers might just ignore them others will throw an error. it should be:
module part1(clk,clr,cntEn,dout);
input clk, clr, cntEn;
output dout;
wire w1;
count count_1 (clk, clr, cntEn, w1);
sevenseg sevenseg_1(w1, dout );
endmodule
I think it is also worth pointing out that unless your constrained to Verilog-95 then adopting an ANSI style port declaration is preferred, as it lead to easier to maintain code.
module part1(
input clk, clr, cntEn,
output dout
);
wire w1;
count count_1 (clk, clr, cntEn, w1);
sevenseg sevenseg_1(w1, dout );
endmodule
Module sevenseg also has an incomplete case statement which will lead to implied latches. either add a default or fully specify the output for all options of num:
module sevenseg(num,dout);
input [3:0] num;
output reg [6:0] dout;
always #(*) begin
case(num)
0:dout=7'b1111110;
1:dout=7'b1100000;
2:dout=7'b1011011;
3:dout=7'b1001111;
4:dout=7'b1100110;
5:dout=7'b1101101;
6:dout=7'b1111101;
7:dout=7'b0000111;
8:dout=7'b1111111;
9:dout=7'b1101111;
default: dout='b0;
endcase
end
endmodule

Related

How to get more info in testbench results?

I realize that this may be very easy to fix but I can't find a way to make it work.
My question is how can I get visual signals of CE2 and CEO in this case? I know by looking on RTL Scheme CE2 and CEO isn't connected to pins. And I just can't connect them.
CE2 should be ON when first counter reach 9 but on waveform its always as X. And CEO should be ON when Q is 9 but on waveform its always Z.
This circuit is just for self learning.
Testbench
Circuit Scheme
TOP MODULE:
`timescale 1ns / 1ps
module top(
input CLK,
input CLR,
input CE,
input CE2,
output reg [3:0] Q,
output reg [3:0] Q2,
output wire CEO,
output CEO2
);
wire CLK;
wire CLR;
wire CENABLE;
wire CE2;
wire Q;
wire Q2;
wire CEO;
wire CEO2;
licznik licznik(.CLK(CLK),.CLR(CLR),.CE(CE),.CEO(CENABLE),.Q(Q));
licznik2 licznik2(.CLK(CLK),.CLR(CLR),.CE2(CENABLE),.Q2(Q2),.CEO2(CEO2));
endmodule
TESTBENCH:
`timescale 1ns / 1ps
module testbench;
reg CLK;
reg CLR;
reg CE;
reg CE2;
wire [3:0] Q;
wire [3:0] Q2;
wire CEO;
wire CEO2;
top UUT (
.CLK(CLK),
.CLR(CLR),
.CE(CE),
.CE2(CE2),
.Q(Q),
.Q2(Q2),
.CEO(CEO),
.CEO2(CEO2)
);
initial CLK=1'b0;
always #5 CLK=~CLK;
initial
begin
CLR = 1'b1;
CE= 1'b1;
#18 CLR = 1'b0;
end
endmodule
FIRST MODULE:
`timescale 1ns / 1ps
module licznik(
input CLK,
input CLR,
input CE,
output reg [3:0] Q,
output CEO
);
always #(posedge CLK or posedge CLR)
if(CLR)
Q <= 4'd0;
else begin
if(CE) begin
if(Q != 4'd9)
Q <= Q + 1;
else
Q <= 4'd0;
end
end
assign CEO = CE & (Q == 4'd9);
endmodule
SECOND MODULE:
`timescale 1ns / 1ps
module licznik2(
input CLK,
input CLR,
input CE2,
output reg [3:0] Q2,
output CEO2
);
always #(posedge CLK or posedge CLR)
if(CLR)
Q2 <= 4'd0;
else begin
if(CE2) begin
if(Q2 != 4'd9)
Q2 <= Q2 + 1;
else
Q2 <= 4'd0;
end
end
assign CEO2 = CE2 & (Q2 == 4'd9);
endmodule
I ran your code on 2 simulators, and I got compile errors on both. Try your code on EDAPlayground.
To fix the compile errors, I removed the wire declarations in module top. To fix the problem with Z on CEO, I replaced CENABLE with CEO. Here is the new top module:
module top(
input CLK,
input CLR,
input CE,
input CE2,
output reg [3:0] Q,
output reg [3:0] Q2,
output wire CEO,
output CEO2
);
licznik licznik(.CLK(CLK),.CLR(CLR),.CE(CE),.CEO(CEO),.Q(Q));
licznik2 licznik2(.CLK(CLK),.CLR(CLR),.CE2(CEO),.Q2(Q2),.CEO2(CEO2));
endmodule
CE2 is X because it is an undriven input. I think you can just delete it.

Why are the outputs not changing/not getting loaded in my single cycle architecture implementation?

I've written the code for the single cycle MIPS Architecture which implements add, sub, multiply and divide. There's a 2D Reg array, A control unit, an ALU. I think I've written it all right, but the opcode I've put in the test bench doesn't seem to be going into the process: the outputs aren't changing at all and I can't understand why. Can anyone tell me why?
////////////////////////////////////////////fixed
module registermemory(
input [3:0]Ra, Rb, Wa, Wd,
input write, input clk,
output [3:0] A,B
);
reg [15:0] memarray [3:0];
integer i;
initial begin
for(i=0;i<=15;i=i+1)
memarray[i]<=4'b0101; ///when the entire 2D array has same value?
end
integer r1,r2,w1;
always#(clk)
begin
r1=Ra;r2=Rb;w1=Wa;
end
assign A = memarray[r1];
assign B = memarray[r2];//assign used outside always. equal to used inside always.
always#(Wd)
begin
if(write)
memarray[w1]=Wd;
end
endmodule
///////////////////////////////
module controlblock(opcode,cntrl,Ra,Rb,Wa,write);
input [13:0]opcode;
output reg[1:0]cntrl;
output reg[3:0]Ra;
output reg[3:0]Rb;
output reg[3:0]Wa;
output reg write; //control signal tells that register has to be written in reg file
always#(opcode) ///why #opcode tho?
begin
cntrl=opcode[13:12];
Ra=opcode[11:8];
Rb=opcode[7:4];
Wa=opcode[3:0];
write=1; //why tho?
end
endmodule
///////////////////////////////
module alu_arith(input[3:0]A, input[1:0] cntrl,
input clk,
input[3:0]B,
output reg[3:0]Wd
);
always#(clk)
begin
case(cntrl)
00:Wd=A+B;
01:Wd=A-B;
10:Wd=A*B;
11:Wd=A/B;
default: Wd=4'b0000;
endcase
end
endmodule
///////////////////////////////////////////////////////
module concat(input [0:13]opcode, input clk, output[3:0]Wd);
wire[3:0]Ra;wire[3:0]Rb;wire[3:0]Wa;wire written;wire[1:0]cntrl;
wire[3:0]A;wire[3:0]B;wire[3:0]Wd;
controlblock a1(opcode,cntrl,Ra,Rb,Wa,write); //
registermemory a2(Ra, Rb, Wa, Wd,write,clk,A,B
); //
alu_arith a3(A,cntrl,clk,B,Wd); //
endmodule
//////////////////////////////////////////////////////////////
module testbench;
reg clk;
reg[13:0]opcode;
wire[3:0]Wd;
wire[1:0] cntrl;
reg[3:0]A,B;
concat a4(opcode,clk,Wd);
initial
clk=0;
always
#2 clk=!clk;
initial begin
$display("\ttime \tclk \tcntrl \tA \tB \tWd ");
$monitor("%d,\t \t%b \t%b \t%b \t%b \t%b",
$time, clk, cntrl, A, B, Wd);
#10 opcode=14'b00010010110100;
#20 opcode=14'b01100010101010;
end
initial
#50 $finish;
endmodule
You declared memarray incorrectly as a 16-bit wide by 4 word deep memory. You want a 4-bit wide by 16 deep:
reg [3:0] memarray [0:15];
When I make this change, I see the Wd output changing.

Why is iverilog complaining about my testbench module?

I'm writing a verilog module for my CompSci class and this module specifically is the data memory module. Structurally and analytically, I'm looking at it and it should work based off of the other files that I have, but I'm not sure why this one specifically is acting up and giving me all x's. Hoping a fresh set of eyes can help find the error I missed. Thanks in advance.
datamem.v:
module datamem(Ina, Inb, enable, readwrite, dataOut, clk, rst);
input wire [31:0] Ina;
input wire [31:0] Inb;
input wire enable;
input wire readwrite;
input wire clk;
input wire rst;
reg [31:0] memory[0:65535];
output reg [31:0] dataOut;
always #(memory[Ina]) begin
dataOut = memory[Ina];
end
always #(posedge clk) begin
if(1'b1 == readwrite) begin
memory[Ina] = Inb;
end
end
endmodule
datamem_tb.v:
module datamem_tb();
reg [31:0] Ina;
reg [31:0] Inb;
reg enable;
reg readwrite;
reg clk;
reg rst;
wire [31:0] dataOut;
datamem DUT (Ina, Inb, enable, readwrite, dataOut, clk, rst);
initial
begin
Ina <= 32'd0;
Inb <= 32'd0;
enable <= 0;
readwrite <= 0;
#20 Ina <= 32'd1234;
#20 Inb <= 32'd1234;
#20 Ina <= 32'd0517;
#20 Inb <= 32'd10259;
end
always #(Ina or Inb)
#1 $display("| Ina = %d | Inb = %d | dataOut = %d |", Ina, Inb, dataOut);
endmodule
A few things as to why you are getting all 'x:
You never run the clock, you need to add something like the following to have the clock toggle:
initial begin
clk = 1'b0;
forever #5 clk = ~clk;
end
You never assert readwrite which is required to write to your memory module (you set it to 0 on line 20 and never change it). Without being written to, memory will retain its original value of 'x for every element
Aside from that, there are a few other issues with your module:
Use implicit sensitive lists (instead of always #(memory[inA]) use always #(*))
Use non-blocking assignment for your memory write (memory[inA] <= inB)
Consider using $monitor instead of $display for your print statements to avoid timing issues, and you only need call it at the beginning of your initial block in your testbench (http://referencedesigner.com/tutorials/verilog/verilog_09.php)
Your rst and enable arent connected to anything.
Another example of a memory unit implementation can be found here:
Data memory unit

4-bit counter using T-flipflop in verilog

I'm trying to design a 4-bit counter with T-flipflop, here's what i did:
1- From a D-flipflop to T-flipflop:
module T_FlipFlop( clk,T, Q);
input wire clk;
input wire T;
output reg Q;
wire D;
initial
begin
Q<=1'b0;
end
assign D= T ^ Q;
always #(negedge clk)
begin
Q<=D;
end
endmodule
with RTL shematic :
following this "D_ff to T_ff" conversion:
2- Then, i instantiated 4 T-flipflops in the top module and connected the output of each flipflop to the clk of the next one:
module Counters_FreqDividers( sysclk,Q1,Q2,Q3,Q4);
input sysclk;
output wire Q1;
output wire Q2;
output wire Q3;
output wire Q4;
T_FlipFlop num_1(.clk(sysclk),.T(1'b1),.Q(Q1));
T_FlipFlop num_2(.clk(Q1),.T(1'b1),.Q(Q2));
T_FlipFlop num_3(.clk(Q2),.T(1'b1),.Q(Q3));
T_FlipFlop num_4(.clk(Q3),.T(1'b1),.Q(Q4));
endmodule
with RTL schematic :
to follow this diagram:
We know that T-flipflop is just a JK-flipflop with J and K connected to each other and that's what we have here, so consider them as T-flipflops.
3-The simulation:
4- Finally, my questions:
1) why Q1 is the ONLY output that operates properly?
2) Why Q2, Q3, Q4 starts with 1 although i have initialized them as 0?
I can't figure out what's missing, i tried to play around but nothing worked and i'm stuck here!
Edit: my testbench:
module test;
// Inputs
reg sysclk;
// Outputs
wire Q1;
wire Q2;
wire Q3;
wire Q4;
// Instantiate the Unit Under Test (UUT)
Counters_FreqDividers uut (
.sysclk(sysclk),
.Q1(Q1),
.Q2(Q2),
.Q3(Q3),
.Q4(Q4)
);
initial begin
// Initialize Inputs
sysclk <= 1'b1;
#200 $finish();
end
always #5 sysclk=~sysclk;
endmodule

Error (10219): Verilog HDL Continuous Assignment error at Mux.v(19): object "muxout" on left-hand side of assignment must have a net type

I want to make Frequency Divider with Counter and MUX.
I make 3 module for project
// 4-bit Counter
module Counter (input clk, input reset, output reg[3:0] out);
always#(posedge clk or posedge reset)
begin
if(reset)
out = 4'b0000;
else
begin
if(clk)
if(out < 4'b1111)
out = out + 4'b0001;
else
out = 4'b0000;
end
end
endmodule
//module 4by1 Mux
module Mux (input [3:0] muxin , input [1:0] sel, output reg muxout);
function _4by1mux;
input [3:0] muxin;
input [1:0] sel;
case (sel)
2'b00 : _4by1mux = muxin[0];
2'b01 : _4by1mux = muxin[1];
2'b10 : _4by1mux = muxin[2];
2'b11 : _4by1mux = muxin[3];
endcase
endfunction
assign muxout = _4by1mux(muxin, sel);
endmodule
//module freqDivider
module freqDivider(input clk, input reset, input [1:0] sel, output reg muxout);
wire [3:0]counterbus;
Counter ct1 (clk, reset, counterbus);
Mux mux1 (counterbus, sel, muxout);
endmodule
module freqDivider is top, and I call module Counter and Mux
but module Mux has problem with
Error (10219): Verilog HDL Continuous Assignment error at Mux.v(19):
object "muxout" on left-hand side of assignment must have a net type
this error
ps. input sel will be changed by time
The error is a result of the muxout output having type reg instead of type wire. In verilog, lines can have two overarching types, either nets (like wire type) or variables (like reg types). To assign values/logic to net types, you need to use assign statements and not always blocks. To assign values/logic to variable types, you can only use always blocks and not assign statements. So, you can either make your assign in the Mux module an always block or, for an easier solution, don't make the muxout output a reg, just leave out the reg keyword and it will be a wire.
Error is that you have declared mux_out as reg type, instead of wire type. Default type of any port is wire. You are doing continuous assignment on that net through assign keyword. And on reg type nets, assignment can only be done inside procedural block (initial, always).
Change to mux_out from output reg to output only.

Resources