Im making a simple up counter with D flip-flop in Verilog.
The module MUST be made with structural (Gates like AND OR NOT etc..)
module dff (Q,D, CK);
input CK,D;
output Q;
wire NM,NCK;
wire NQ,M;
nand DN1 (NM,D,CK);
nand DN2 (M,NM,CK);
nand DN3 (Q,NQ,NM);
nand ND4 (QN,Q,M);
endmodule
This is what I have got. But I failed to make working testbench even to test the DFF
module tb;
reg D, CK;
wire Q;
dff p0(Q, D, CK);
//jkstruct m0(q, qn, t, cp);
initial begin
D = 0;
CK = 1;
#100;
$display(Q);
D = 0;
CK = 1;
#50
$display(Q);
D = 1;
CK = 0;
#50
$display(Q);
D = 1;
CK = 1;
$display(Q);
$finish;
end
endmodule
Im newbie in this programming language so can you give me the examples please?
Verilog allows a single bit wire to be inferred without a declaration. This can help reduce the number of lines of code but increases the risk of spiting a net with a type and never getting an error or warning. In this case, QN and NQ should be the same net.
FYI: You implemented a D latch, not a D flip-flop.
Related
I am not sure, what exactly the error is. I think, my indexing in the for-loop is not Verilog-compatible, but I might be wrong.
Is it allowed to index like this (a[(4*i)+3:4*i]) in a for-loop just like in C/C++?
Here is a piece of my code, so the for-loop would make more sense
module testing(
input [399:0] a, b,
input cin,
output reg cout,
output reg [399:0] sum );
// bcd needs 4 bits + 1-bit carry --> 5 bits [4:0]
reg [4:0] temp_1;
always #(*) begin
for (int i = 0; i < 100; i++) begin
if (i == 0) begin // taking care of cin so the rest of the loop works smoothly
temp_1[4:0] = a[3:0] + b[3:0] + cin;
sum[3:0] = temp_1[3:0];
cout = temp_1[4];
end
else begin
temp_1[4:0] = a[(4*i)+3:4*i] + b[(4*i)+3:4*i] + cout;
sum[(4*i)+3:4*i] = temp_1[3:0];
cout = temp_1[4];
end
end
end
endmodule
This might seem obvious. I'm doing the exercises from:
HDLBits and got stuck on this one in particular for a long time (This solution isn't the one intended for the exercise).
Error messages Quartus:
Error (10734): Verilog HDL error at testing.v(46): i is not a constant File: ../testing.v Line: 46
Error (10734): Verilog HDL error at testing.v(47): i is not a constant File: ../testing.v Line: 47
But I tried the same way in indexing and got the same error
The error appears because Verilog does not allow variables at both indices of a part select (bus slice indexes).
The most dynamic thing that can be done involves the indexed part select.
Here is a related but not duplicate What is `+:` and `-:`? SO question.
Variations of this question are common on SO and other programmable logic design forums.
I took your example and used the -: operator rather than the : and changed the RHS of this to a constant. This version compiles.
module testing(
input [399:0] a, b,
input cin,
output reg cout,
output reg [399:0] sum );
// bcd needs 4 bits + 1-bit carry --> 5 bits [4:0]
reg [4:0] temp_1;
always #(*) begin
for (int i = 0; i < 100; i++) begin
if (i == 0) begin // taking care of cin so the rest of the loop works smoothly
temp_1[4:0] = a[3:0] + b[3:0] + cin;
sum[3:0] = temp_1[3:0];
cout = temp_1[4];
end
else begin
temp_1[4:0] = a[(4*i)+3-:4] + b[(4*i)+3-:4] + cout;
sum[(4*i)+3-:4] = temp_1[3:0];
cout = temp_1[4];
end
end
end
endmodule
The code will not behave as you wanted it to using the indexed part select.
You can use other operators that are more dynamic to create the behavior you need.
For example shifting, and masking.
Recommend you research what others have done, then ask again if it still is not clear.
My college teacher asked for me to implement a Johnson Counter and it's test bench, with an width<=32 (he calls it an N parameter), and the implementation has to use generate/for structures. Although I had learned a little about Johnson Counter, I don't know how to use generate in this case, and I had some errors when I tried to run the test bench. Here is my implementation so far:
module johnsonCounter #(parameter N = 32)
(
input clk,
input rstn,
output reg [N-1:0] out
);
always # (posedge clk) begin
if (!rstn)
out <= 1;
else begin
out[N-1] <= ~out[0];
generate
for (int i = 0; i < N-1; i=i+1) begin
out[i] <= out[i+1];
end
endgenerate
end
end
endmodule
Here is the test bench:
module tb;
parameter N = 32;
reg clk;
reg rstn;
wire [N-1:0] out;
johnsonCounter u0 (.clk (clk),
.rstn (rstn),
.out (out));
always #10 clk = ~clk;
initial begin
{clk, rstn} <= 0;
$monitor ("T=%0t out=%b", $time, out);
repeat (2) #(posedge clk);
rstn <= 1;
repeat (15) #(posedge clk);
$finish;
end
initial begin
$dumpvars;
$dumpfile("dump.vcd");
end
endmodule
These are the errors:
ERROR VCP2000 "Syntax error. Unexpected token: generate[_GENERATE]. This is a Verilog keyword since IEEE Std 1364-2001 and cannot be used as an identifier. Use -v95 argument for compilation." "design.sv" 13 7
ERROR VCP2020 "begin...end pair(s) mismatch detected. 2 <end> tokens are missing." "design.sv" 17 7
ERROR VCP2020 "module/macromodule...endmodule pair(s) mismatch detected. 1 <endmodule> tokens are missing." "design.sv" 17 7
ERROR VCP2000 "Syntax error. Unexpected token: endgenerate[_ENDGENERATE]. This is a Verilog keyword since IEEE Std 1364-2001 and cannot be used as an identifier. Use -v95 argument for compilation." "design.sv" 17 7
Any help is welcome =)
It is illegal to use generate in that way.
For your code, just a for loop is needed (without generate):
always # (posedge clk) begin
if (!rstn)
out <= 1;
else begin
out[N-1] <= ~out[0];
for (int i = 0; i < N-1; i=i+1) begin
out[i] <= out[i+1];
end
end
end
For generate syntax, refer to the IEEE Std 1800-2017, section 27. Generate constructs.
I tried implementing it using the generate construct. I am also new at this, so if anybody sees any problem or error, or could provide any suggestion to improve performance, I would appreciate it.
Regarding your question, I always use generate to instantiate several modules, I think it makes my code cleaner and easier to understand. So what I did is to define a simple D flip-flop module, which I will use to instantiate it. If you want to use generate, you have to define an iterative variable with genvar. Also, you should use generate outside an always block (I don't know if there is a situation where you could use it inside the always block). Below, you can see the code.
module ff
(
input clk,
input rstn,
input d,
output reg q,
output reg qn
);
always #(posedge clk)
begin
if(!rstn)
begin
q <= 0;
qn <= 1;
end
else
begin
q <= d;
qn <= ~d;
end
end
endmodule
module johnsonCounter #(parameter N = 4)
(
input clk,
input rstn,
output [N-1:0] out,
output [N-1:0] nout
);
genvar i;
generate
for (i = 0; i < N-1; i=i+1) begin
ff flip (.clk(clk), .rstn(rstn), .d(out[i+1]), .q(out[i]), .qn(nout[i]));
end
endgenerate
ff lastFlip (.clk(clk), .rstn(clk), .d(nout[0]), .q(out[N-1]), .qn(nout[N-1]));
endmodule
Here you have the testbench, too. One thing I changed from your code is the dumpfile line. It should go before dumpvar.
module tb;
parameter N = 4;
reg clk;
reg rstn;
wire [N-1:0] out;
johnsonCounter u0 (.clk (clk),
.rstn (rstn),
.out (out));
always #10 clk = ~clk;
initial begin
{clk, rstn} <= 0;
$monitor ("T=%0t out=%b", $time, out);
repeat (2) #(posedge clk);
rstn <= 1;
repeat (15) #(posedge clk);
$finish;
end
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
endmodule
This code was tested using EDA Playground and it worked fine but, as I said, I am not an expert, so if anybody finds any error or have any suggestion, it is welcome.
This question already has answers here:
What is the difference between reg and wire in a verilog module?
(3 answers)
Closed 2 years ago.
I have some code in VHDL I am trying to convert to Verilog.
The VHDL code works fine
library ieee;
use ieee.std_logic_1164.all;
entity find_errors is port(
a: bit_vector(0 to 3);
b: out std_logic_vector(3 downto 0);
c: in bit_vector(5 downto 0));
end find_errors;
architecture not_good of find_errors is
begin
my_label: process (a,c)
begin
if c = "111111" then
b <= To_StdLogicVector(a);
else
b <= "0101";
end if;
end process;
end not_good;
The Verilog code I have, gets errors "Illegal reference to net "bw"."
and
Register is illegal in left-hand side of continuous assignment
module find_errors(
input [3:0]a,
output [3:0]b,
input [5:0]c
);
wire [0:3]aw;
wire [3:0]bw;
reg [5:0]creg;
assign aw = a;
assign b = bw;
assign creg = c;
always #(a,c)
begin
if (creg == 4'b1111)
bw <= aw;
else
bw <= 4'b0101;
end
endmodule
It looks pretty close but there are a few things that are problems/errors that need to be fixed, see inline comments in fixed code:
module find_errors(
input wire [3:0] a, // Better to be explicit about the types even if
// its not strictly necessary
output reg [3:0] b, // As mentioned in the comments, the error youre
// seeing is because b is a net type by default; when
// describing logic in any always block, you need to
// use variable types, like reg or logic (for
// SystemVerilog); see the comment for a thread
// describing the difference
input wire [5:0] c);
// You dont really need any local signals as the logic is pretty simple
always #(*) begin // Always use either always #(*), assign or
// always_comb (if using SystemVerilog) for combinational logic
if (c == 6'b111111)
b = a; // For combinational logic, use blocking assignment ("=")
// instead of non-blocking assignment ("<="), NBA is used for
// registers/sequential logic
else
b = 4'b0101;
end
endmodule
aw and creg are unnecessary, and bw needs to be declared as reg.
module find_errors(
input [3:0] a,
output [3:0] b,
input [5:0] c
);
reg [3:0] bw;
assign b = bw;
always #(a,c)
begin
if (c == 4'b1111)
bw <= a;
else
bw <= 4'b0101;
end
endmodule
Since there is no sequential logic, you don't even need an always block:
module find_errors(
input [3:0] a,
output [3:0] b,
input [5:0] c
);
assign b = (c == 4'b1111) ? a : 4'b0101;
endmodule
I am trying to determine how to turn this code into a 4-bit adder/subtractor using a fulladder. Right now it is doing the adding but I don't know how to do the subtract part.
module Adder #(parameter N = 4)(
output wire [N-1:0] sum, // sum
output wire co, // carry
input wire [N-1:0] x,
input wire [N-1:0] y,
input wire is_sub;
);
wire [N:0] c;
assign c[0] = 1'b0;
assign co = c[N];
genvar i;
generate
for (i = 0; i < N; i=i+1)
begin : counter_gen_label
FA FAInst (
.s(sum[i]),
.co(c[i+1]),
.a(x[i]),
.b(y[i]),
.cin(c[i]),
.is_sub(is_sub)
);
end
endgenerate
endmodule
module FA(
output reg s,
output reg co,
input wire a,
input wire b,
input wire cin,
input wire is_sub
);
always #(*)
begin
s = a ^ b ^ cin;
co = (a & b) | (a & cin) | (b & cin);
end
endmodule
How would I go by doing the subtraction inside the FA module?
Thanks!
FA does not need to use is_sub input.
Replace c[0] = 1'b0; with c[0] = is_sub;, and .b(y[i]) with .b(y[i] ^ is_sub).
This is from x - y = x + y' + 1 where y' means inverted y.
I'm trying to program my NEXYS2 board with a SR latch with NAND gates with an enable signal C. My inputs are (S, R, C) and outputs are (Q, Qbar). below is some code in VHDL that I tried but keep getting errors. also the schematics are below if that helps anyone to understand my question. if you know it in verilog that's okay too.
Thank you in advance
process(S,R,C,Q,Qbar)
begin
if (C = '1') then
Q <= (R nand Qbar);
Qbar <= (S nand Q);
end if;
end process;
First off, your implementation of your schematic is incorrect: R should be
~S, and S should be ~R. try tracing the logic through with S or R equal to 1
when C is 1 - the outputs should set high.
Corrected Verilog (I've only got Altera & Verilog here):
module top(
input wire S, R, C,
output reg Q, Qbar);
always #(S, R, C, Q, Qbar)
if(C) begin
Q <= (~R & Q) | S;
Qbar <= (~S & Q) | R;
end
endmodule
This synthesises Ok on Altera, with 2 warnings along the lines of
Warning (10240): Verilog HDL Always Construct warning at test.v(5): inferring latch(es) for variable "Q", which holds its previous value in one or more paths through the always construct
and a warning from the timing analyser that it analysed two combinational
loops as latches. The technology view looks plausible, but you have got a
problem with this coding style, which could lead to issues.
The problem is that you explicitly code the only feedback paths, but you also
leave the synthesiser to infer a latch. Your code includes if(C = '1'), so the
synthesiser infers memory behaviour - a latch - when C is not 1. However, this
is pointless, since you're also telling it explicitly where the latch is with
your feedback paths. Don't do both; it's a mistake to assume that any
synthesiser is smart enough to figure out what you really meant. Here's a
version that leaves no doubt about what you want:
module top(
input wire S, R, C,
output wire Q, Qbar);
wire S2 = ~(C & S);
wire R2 = ~(C & R);
assign Q = ~(S2 & Qbar);
assign Qbar = ~(R2 & Q);
endmodule
This instead gives two 'Found combinational loop of 2 nodes' warnings, as
you'd expect. This also synthesises Ok, and the RTL/technology views look Ok,
at first sight.
Standard disclaimer: timing analsysers are not good at timing designs with
combinational loops. this will probably all just work if you're just playing
around, but if this is a real design you'll need to think hard about your
constraints, and whether the analyser has actually traced through your
feedback path (it probably hasn't). You'll need to do a timing sim with sdf
back-annotation to confirm that it actually works.
Your schematic is correct.
The problem is in your VHDL code, because you didn't specify the circuit's functionalities completely (note that the output values for c='0' were not defined), which causes the inference of latches (only registered circuits can be designed with incomplete specifications because then the resulting signals are stored in D-type flip-flops anyway).
You can do the following (among other alternatives):
entity sr_latch is
port (
s, r, c: in bit;
q, qbar: buffer bit);
end entity;
architecture sr_latch of sr_latch is
begin
q <= (s nand c) nand qbar;
qbar <= (r nand c) nand q;
end architecture