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.
Related
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'm trying to create a Shift Register, by using multiplication (*2) to shift bits one position.
However, when I do it, ISE (Xilinx IDE) says me that this expression has x2 the number of elements the original signal has.
To be specific, I've:
if rising_edge(clk) then
registro <= unsigned(sequence);
registro <= registro * 2;
-- Just adds into the last position the new bit, Sin (signal input)
registro <= registro or (Sin, others => '0');
sequence <= std_logic_vector(registro);
end if;
And before, I've declared:
signal Sin : std_logic;
signal sequence : std_logic_vector(0 to 14) := "100101010000000";
signal registro : unsigned (0 to 14);
So I'm getting the error (at multiplication line):
Expression has 30 elements ; expected 15
So, why does it creates a x2 sized vector, if I've only multiplied *2?
What am I missing? How can I accomplish it?
Thank you in advance
Word width grows because you have used multiplication.
Multiplying 2 16-bit unsigned numbers gives you a 32 bit unsigned, in general.
Now it would be possible to optimise your specific case of multiplication by a constant, 2, and have synthesis do the correct thing. In which case the error message would change to
Expression has 16 elements ; expected 15
but why should the synthesis tool bother?
Use a left shift instead, either using a left (right?) shift operator, or explicit slicing and concatenation, for example:
registro <= registro(1 to registro'length-1) & '0';
Incidentally:
Using ascending bit order range is quite unconventional for arithmetic : all I can say is good luck with that...
you have three assignments to the same signal within the same process; only the last one will take effect. (See Is process in VHDL reentrant? for some information on the semantics of signal assignment)
If you declared "sequence" as unsigned in the first place you'd save a lot of unnecessary conversions and the code inside the process would reduce to a single statement, something like
sequence <= ('0' & sequence(0 to sequence'length-2)) or
(0 => Sin, others => '0') when rising_edge(clk);
I am utterly unfamiliar with "wrong way round" arithmetic so I cannot vouch that the shifts actually do what you want.
I am doing some investigation on what kind of code does/does not generate latches on different synthesizers. The code below drives a 7-segment display from a 4-bit input. I would expect it not to generate latches, because all possible cases are covered in the conditional signal assignment.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity seven_seg_conditional is
port (
value: in std_logic_vector(3 downto 0);
digit: out std_logic_vector(6 downto 0)
);
end;
architecture behavior of seven_seg_conditional is
signal value_int: integer range 0 to 15;
begin
value_int <= to_integer(unsigned(value));
digit <=
"0111111" when value_int = 0 else
"0000110" when value_int = 1 else
"1011011" when value_int = 2 else
"1001111" when value_int = 3 else
"1100110" when value_int = 4 else
"1101101" when value_int = 5 else
"1111101" when value_int = 6 else
"0000111" when value_int = 7 else
"1111111" when value_int = 8 else
"1101111" when value_int = 9 else
"1110111" when value_int = 10 else
"1111100" when value_int = 11 else
"0111001" when value_int = 12 else
"1011110" when value_int = 13 else
"1111001" when value_int = 14 else
"1110001" when value_int = 15;
end;
If I run it through Quartus 13.0, a latch is generated on each output. Is this correct behavior for a synthesizer as per the ongoing standards?
Note: if I rewrite the code using a case statement then there are no latches, even though I never added a when others clause. If I add an unconditional else clause at the end there are no latches as well.
If I run it through Quartus 13.0, a latch is generated on each output.
Is this correct behavior for a synthesizer as per the ongoing
standards?
The applicable standard (IEEE Std 1076.6-1999/2004, 8.9.5.1 Conditional signal assignment) defines what syntactical constructs will be recognized for synthesis, not how they are interpreted. That leaves the syntactical meaning found in the VHDL LRM (IEEE Std 1076-1993/2002, year supported varying by synthesis vendor, generally not all inclusive either, no standard for VHDL 2008).
When you add an "unconditional else":
"1110001" when value_int = 15 else (others => 'X');
end;
The thinking goes that conversion functions are essentially ignored and the equivalent condition expression to_integer(unsigned(value)) = 15, etc. doesn't cover all the choices for value. Also 'X' assignments are ignored for synthesis and the else requires something.
A concurrent conditional signal assignment has an equivalent process comprised of if then elsif then ... end if. You could postulate the presence of the trailing else conveys that all choices are covered.
Expressions are evaluated during simulation (e.g. value_int = 15). There either needs to be something in the syntax to signal all choices are covered or the choices have to be all inclusive.
Note that a VHDL simulator get's rid of the uncertainty in your original concurrent signal assignment statement expressions by the package numeric_std TO_INTEGER outputting an assertion warning - "metavalue detected, returning 0". Using value_int has the savings grace of only generating one warning when a value other than a '1' or '0' is detected as an element of the array value.
The range of the integer value_int implies a bit array size. Type conversions have no real meaning for synthesis which is concerned with binary logic.
If you ignore conversion functions and through synthesis 'magic' assume say 15 is representable as a binary value then there isn't anything signaling the choices are all inclusive without the trailing else to not infer latches.
Could a vendor do a better job converting the concurrent signal assignment to logic? Likely, by not deferring to the original array subtype value. Is the behavior you describe correct for ongoing standards? It appears to be. Standards tend to shy away from areas that can conflict between vendors covering instead common ground.
You could also imagine there should be some reasonable limit on the inference of latches, in this case because of combinatorial delays (difference in rise and fall times) in the evaluated expressions. It isn't generally safe to infer a latch enable by gates representing state, there are cases where inferring latch enables should be an error although the inference of latches would work with a one hot state machine or ring counter, which doesn't match the expressions evaluating value.
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
How do you implement a hardware random number generator in an HDL (verilog)?
What options need to be considered?
This question is following the self-answer format. Addition answers and updates are encouraged.
As noted in Morgan's answer this will only produce a single random bit. The number of bits in the LFSR only set how many values you get before the sequence repeats. If you want an N bit random number you have to run the LFSR for N cycles. However, if you want a new number every clock cycle the other option is to unroll the loop and predict what the number will be in N cycles. Repeating Morgan's example below, but to get a 5 bit number each cycle:
module fibonacci_lfsr_5bit(
input clk,
input rst_n,
output reg [4:0] data
);
reg [4:0] data_next;
always #* begin
data_next[4] = data[4]^data[1];
data_next[3] = data[3]^data[0];
data_next[2] = data[2]^data_next[4];
data_next[1] = data[1]^data_next[3];
data_next[0] = data[0]^data_next[2];
end
always #(posedge clk or negedge rst_n)
if(!rst_n)
data <= 5'h1f;
else
data <= data_next;
endmodule
Edit: Added a new version below which doesn't require you to do the math. Just put it in a loop and let the synthesis tool figure out the logic:
module fibonacci_lfsr_nbit
#(parameter BITS = 5)
(
input clk,
input rst_n,
output reg [4:0] data
);
reg [4:0] data_next;
always_comb begin
data_next = data;
repeat(BITS) begin
data_next = {(data_next[4]^data_next[1]), data_next[4:1]};
end
end
always_ff #(posedge clk or negedge reset) begin
if(!rst_n)
data <= 5'h1f;
else
data <= data_next;
end
end
endmodule
I would like to make the LFSR length parameterizable as well, but that is much more difficult since the feedback taps don't follow a simple pattern.
This is a TRNG (True random number generator) that works on an FPGA. It is basically an LFSR type structure without the flip flops, so it is a combinatorial loop that runs continuously. The signal oscillates chaotically, when you combine several of these modules and XOR bits you get a truly random bit, since the jitter from each combines. The maximum clock rate you can run this at depends on your FPGA, you should test the randomness with a testing suite like diehard, dieharder, STS or TestU01.
These are called Galois Ring Oscillators(GARO). There are other TRNGs which use less power and area, but they are tricker to operate and write, usually relying on tuning delays to make a flipflop go metastable.
module GARO (input stop,clk, reset, output random);
(* OPTIMIZE="OFF" *) //stop *xilinx* tools optimizing this away
wire [31:1] stage /* synthesis keep */; //stop *altera* tools optimizing this away
reg meta1, meta2;
assign random = meta2;
always#(posedge clk or negedge reset)
if(!reset)
begin
meta1 <= 1'b0;
meta2 <= 1'b0;
end
else if(clk)
begin
meta1 <= stage[1];
meta2 <= meta1;
end
assign stage[1] = ~&{stage[2] ^ stage[1],stop};
assign stage[2] = !stage[3];
assign stage[3] = !stage[4] ^ stage[1];
assign stage[4] = !stage[5] ^ stage[1];
assign stage[5] = !stage[6] ^ stage[1];
assign stage[6] = !stage[7] ^ stage[1];
assign stage[7] = !stage[8];
assign stage[8] = !stage[9] ^ stage[1];
assign stage[9] = !stage[10] ^ stage[1];
assign stage[10] = !stage[11];
assign stage[11] = !stage[12];
assign stage[12] = !stage[13] ^ stage[1];
assign stage[13] = !stage[14];
assign stage[14] = !stage[15] ^ stage[1];
assign stage[15] = !stage[16] ^ stage[1];
assign stage[16] = !stage[17] ^ stage[1];
assign stage[17] = !stage[18];
assign stage[18] = !stage[19];
assign stage[19] = !stage[20] ^ stage[1];
assign stage[20] = !stage[21] ^ stage[1];
assign stage[21] = !stage[22];
assign stage[22] = !stage[23];
assign stage[23] = !stage[24];
assign stage[24] = !stage[25];
assign stage[25] = !stage[26];
assign stage[26] = !stage[27] ^ stage[1];
assign stage[27] = !stage[28];
assign stage[28] = !stage[29];
assign stage[29] = !stage[30];
assign stage[30] = !stage[31];
assign stage[31] = !stage[1];
endmodule
An LFSR is often the first port of call. Implementation is relatively simple, a shift register with a number of terms XORd together to create the feedback term.
When considering the implementation of the LFSR, the bit width of the random number and the repeatability of the number need to be considered. With N bits a Maximal LFSR will have (2**N) - 1 states. All zero state can not be used with out additional hardware.
An example 4 bit LFSR with taps a bit 0 and bit 4:
module fibonacci_lfsr(
input clk,
input rst_n,
output [4:0] data
);
wire feedback = data[4] ^ data[1] ;
always #(posedge clk or negedge rst_n)
if (~rst_n)
data <= 4'hf;
else
data <= {data[3:0], feedback} ;
endmodule
Choosing tap points and finding out the sequence length (number of numbers before it repeats) can be found from this table.
For example a sequence of 17,820,000, 30 bits wide could use taps of :
0x20000029 => bits "100000000000000000000000101001"
0x2000005E => bits "100000000000000000000001011110"
0x20000089 => bits "100000000000000000000010001001"
The first would have a feedback term of:
feedback = data[29] ^ data[5] ^ data[3] ^ data[0];
If you are unsure of the order of the taps, remember that the MSB will always be a feedback point. The Last (tap) feedback point defines the effective length of the LFSR, after that it would just be a shift register and have no bearing on the feedback sequence.
If you needed a sequence of 69,273,666 you would have to implement a 31 bit LFSR and choose 30 bits for your random number.
LFSRs are a great way to create a 1-bit random number stream but if you are taking multiple consecutive bits that there is a correlation between values, it is the same number shifted plus dither bit. If the number is being used as a dither stream you may want to introduce a mapping layer, for example swap every other bit. Alternatively use an LFSR of different length or tap points for each bit.
Further Reading
Efficient Shift Registers, LFSR Counters, and Long Pseudo-Random Sequence Generators,
A Xilinx app note by Peter Alfke.
Linear Feedback Shift Registers in Virtex Devices,
A Xilinx app note by Maria George and Peter Alfke.