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
Related
I am trying to make a 4-bit adder and test it. I decided to use wait to determine when the adder circuit is done by checking when my sum and carry_out are >= 0. The inputs for the circuit are given as command line arguments. I am constructing my 4-bit adder using my full adder which I was able test successfully using this method.
full_adder.v
//Behavioral Verilog
module full_adder (input a, input b, input cin, output s, output cout);
assign s = a ^ b ^ cin;
assign cout = (a && b) || (a && cin) || (b && cin);
endmodule
4_bit_adder.v
module four_bit_adder(input [0:3] x, input [0:3] y, input carry_in, output [0:3] sum, output carry_out);
full_adder add1(x[0], y[0], sum[0], carry_in, carry1);
full_adder add2(x[1], y[1], sum[1], carry1, carry2);
full_adder add3(x[2], y[2], sum[2], carry2, carry3);
full_adder add4(x[3], y[3], sum[3], carry3, carry_out);
endmodule
4_bit_adder_tester.v
module four_bit_adder_test;
reg [0:3]x;
reg [0:3]y;
reg carry_in;
wire sum;
wire carry_out;
four_bit_adder adder(x, y, carry_in, sum, carry_out);
initial begin
$display("Here");
if (!$value$plusargs("x=%d", x)) begin
$display("ERROR: please specify +x=<value> to start.");
$finish;
end
if (!$value$plusargs("y=%d", y)) begin
$display("ERROR: please specify +y=<value> to start.");
$finish;
end
if (!$value$plusargs("carry_in=%d", carry_in)) begin
$display("ERROR: please specify +carry_in=<value> to start.");
$finish;
end
wait(sum >= 0 && carry_out>= 0) $display("sum=%d, carry_out=%d", sum, carry_out);
$finish;
end
endmodule
The problem is that carry_out remains at x so the sum and carry_out variables never get printed. I tried printing out the value of carry_out, and I think the logic in my circuits should work. Is this a valid way of testing my Verilog code?
That not a recommended way of testing because you get no output if the data is incorrect.
A better way is checking if the output matches what you expect
$display("Expected %b + %b + %b = %b", x,y,carry_in, {x+y+carry_in});
#1 // let output propagate
if ( {carry_out,sum} == x + y + carry_in )
$display("passed sum=%b, carry_out=%b", sum, carry_out);
else
$display("failed sum=%b, carry_out=%b", sum, carry_out);
end
This gives you a better picture of what is going wrong. You sill see that the output is z which means you have not connected thing up properly.
Also, get rid of all warning messages.
You need to pay close attention to your simulator log files because there should be warning messages which will point out the problem in your code. For example, on EDA Playground, I see this warning:
Warning-[PCWM-W] Port connection width mismatch
testbench.sv, 21
"four_bit_adder adder(x, y, carry_in, sum, carry_out);"
The following 1-bit expression is connected to 4-bit port "sum" of module
"four_bit_adder", instance "adder".
Expression: sum
Instantiated module defined at: "testbench.sv", 8
The warning goes away when you change:
wire sum;
to:
wire [0:3] sum;
You can use wait, but you should account for the situation when the expression is never true. In this case, you could add a testbench timeout which ends the simulation cleanly after a reasonable amount of time. For example, add a second initial block in four_bit_adder_test:
initial begin
#50 $display("Error: timeout");
$finish;
end
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
Lets say I have a input.
inputData : in std_logic_vector(63 downto 0)
At the moment I handle all 8 data bytes from inputData.
I have a fsm which processes the data.
For Example:
State A, State B, State C for processing inputData(7 downto 0)
again
State A, State B, State C for processing inputData(15 downto 8)
.
.
.
State A, State B, State C for processing inputData(63 downto 56)
At the end I go throw State D, E and F...
Now I want to make this more flexible.
To make this possible I have now two inputs:
inputData : in std_logic_vector(63 downto 0)
dataLength: in std_logic_vector(3 downto 0)
Now it could be that I have only 3 Bytes of inputData that I want to handle.
For example:
State A, State B, State C for processing inputData(7 downto 0)
wait a little bit and then again
State A, State B, State C for processing inputData(15 downto 8)
wait a little bit and then again
State A, State B, State C for processing inputData(23 downto 16)
wait a little bit and then again
At the end I go throw State D, E and F...
Should or can I use the For-Statement for this or should I use a simple counter?
Is it correct when I do the following when I want to use the For-Statement?
Pseudocode:
process (clk)
begin
for I in 0 ... dataLength loop
if(I not dataLength) then
Go though State A,B,C with dataByte I
else
Go though State A,B,C with dataByte I
and then through State D, E, F and then break ...
end if
end loop;
end process;
Yes you can use the for loop in 2 ways:
if data length is known at compilation time (e.g. generic constant) you can use the construct: for I in 0 to datalength-1 GENERATE
if data length can change during runtime the you need to use: for I in 0 to datalength-1 LOOP
Please notice that, because I used "datalength-1" you don't need the check if(I not datalength) since you will never go to actual datalength
I hope that answers your question.
The answer depends on what do you want to achieve. I don't mean the general computation, but more what cycle timing is wished?
Solution 1:
Each computation requires 1 clock cycle and is equal to one FSM state. Then you would either need as many FSM states. Not a very generic approach, because changing the input width needs more fixed coded states.
The better solution is a counter that gives:
a. the index to process the input data
b. the condition to leave the current FSM state after processing all input bytes
Solution 2:
If all data can be process in just one clock cycle (be careful of the resulting maximum delay), then you can use a for .. loop statement and unroll all computations in one clock cycle / FSM state.
I am trying to convert a big chunk of code from tdf (text design file) to vhdl.
There is a state machine implemented in this tdf file.
Y <= state0 # state1 # state2 # state3 // start at state 0 and stop at state 3
How do I write this above statement in VHDL, assuming I have all states defined.
Any ideas ?
Text Design File (.tdf)
An ASCII text file (with the extension .tdf) written in the Altera Hardware Description Language (AHDL).
AHDL is a VHDL syntax subset superimposed on the majority of the ABEL language syntax (which is more Verilog/C like).
From the ABEL-HDL Reference Manual ABEL-HDL Reference Manual, Operators, Expressions and Equations page 24, and Table 1-3 Logical Operators Page 25 we see # is an OR operator.
There is an AHDL manual See Altera AHDL Language Reference, see Table 3-1. AHDL Symbols (Part 3 of 3) document page 96 (PDF page 117), where we also find # is an OR operator (also represented by the OR reserved word, see Table 3-3. Arithmetic Operators and Comparators Used in Arithmetic Expressions (Part 2 of 2), document page 104 (PDF Page 125).
Also see Table 3.4. Logical Operators Used in Boolean Expressions, document page 107 (PDF Page 128).
Also note from your question "<=" isn't an assignment operator in AHDL or ABEL. (VHDL doesn't have assignment operators, assignment is a a basic operation, operators can be overloaded, basic operations can't be).
Converting this assignment statement depends of whether or not Y and state0 are the same type or not.
If they are the same type:
Y <= state0 or state1 or state2 or state3;
And you can trust synthesis tools to optimize if possible.
If they are of different types the declarations become necessary. (Historically ABEL identifiers for signals are of the same anonymous type, the question is whether you have declared the types as different).
AHDL doesn't support user defined types but does allow enumerated state names.
That would imply a state type along the lines of
type state is (state0, state1, state2, state3, state4,...);
signal sm: state;
And require either a conditional assignment or a case statement.
Y <= '1' when sm = state0 or sm = state1 or sm = state2 or
sm = state3 else
'0';
In a place appropriate for sequential statements:
case sm is
when state0 | state1 | state2 | state2 =>
Y <= '1';
when others =>
Y <= '0';
end case;
or and if statement in a place appropriate for sequential statements:
if sm = state0 or sm = state1 or sm = state2 or sm = state3 then
Y <= '1';
else
Y <= '0';
end if;
Also see this VHDL Reference Manual, Appendix C. VHDL for the ABEL-HDL Designer.
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.