Counting down from an input value in VHDL - vhdl

I'm trying to assign the value of input aa to the signal t in the code below. It compiles successfully, but there is a warning:
WARNING[9]: C:/Modeltech_5.7f/examples/hassan1.vhd(14): (vcom-1013) Initial value of "t" depends on value of signal "aa".
Here is the code:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all ;
use ieee.numeric_std.all;
entity counter is
port(clk :in std_logic;
reset : in std_logic;
aa: in std_logic_vector(3 downto 0);
check : out std_logic_vector(3 downto 0));
end counter;
architecture imp of counter is
signal i:std_logic_vector(3 downto 0):="0000";
signal t:std_logic_vector(3 downto 0):=aa;
begin
process(clk)
begin
if rising_edge(clk) and (t>0) then
t<=t-1;
i<=i+1;
end if;
end process;
check<=i;
end imp;
What should I be doing in order to decrement the input 'aa' in the process? The program is meant to decrement the value at input aa to 0.

It looks like you are trying to implement a down-counter with a load input. In such a counter, when load_enable = '1' you should register the load input value (aa in your case) into an internal signal. When load_enable = '0', you would decrement this count value. Here is a code example that does that:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std_unsigned.all;
entity down_counter is
port (
clock: in std_logic;
reset: in std_logic;
load_enable: in std_logic;
load_data: in std_logic_vector(3 downto 0);
output: out std_logic_vector(3 downto 0)
);
end;
architecture rtl of down_counter is
signal count: std_logic_vector(3 downto 0);
begin
process (clock, reset) begin
if reset then
count <= (others => '0');
elsif rising_edge(clock) then
if load_enable then
count <= load_data;
else
count <= count - 1;
end if;
end if;
end process;
output <= count;
end;
For the record, the code above can be improved, but I didn't want to throw too much stuff at once. It is probably a good idea to use an integer instead of std_logic_vector for your count signal. Also you should check if the count proceeds as you expected, since the example uses the numeric_std_unsigned package. I'd recommend that you change it to numeric_std once you understand the code completely.

Related

TestBench for Bitwise Operators

Can someone help me to create a TestBench Program for the below Program, please?
library ieee;
use ieee.std_logic_1164.all;
entity bitwise is
port( a,b : in std_logic_vector(4 downto 0);
result1, result2, result3, result4, result5, result6 : out std_logic_vector(4 downto 0));
end bitwise;
architecture arch of bitwise is
begin
result1 <= a and b;
result2 <= a or b;
result3 <= a xor b;
result4 <= not a;
result5 <= to_stdlogicvector(to_bitvector(a) sll 1);
result6 <= to_stdlogicvector(to_bitvector(a) srl 1);
end arch;
My Test Bench Program is below: I am stuck to in the Stimulus process where we have to test each and every possibility. It could be either a loop version or just testing possible numbers for each operator.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
entity test_bitwise is
end test_bitwise;
architecture behavior of test_bitwise is
component bitwise;
port( a,b : in std_logic_vector(4 downto 0);
result1, result2, result3, result4 : out std_logic_vector(4 downto 0));
end component;
--INPUTS
signal tb_a : std_logic_vector(4 downto 0) := (others => '0');
`signal tb_b : std_logic_vector(4 downto 0) := (others => '0');
--OUTPUTS
signal tb_result1 : std_logic_vector(7 downto 0);
signal tb_result2 : std_logic_vector(7 downto 0);
signal tb_result3 : std_logic_vector(7 downto 0);
signal tb_result4 : std_logic_vector(7 downto 0);
begin
-- INSTANTIATE THE UNIT UNDER TEST (UUT)
U1_Test : entity work.test_bitwise(behavioral)
port map (a => tb_a,
b => tb_b,
result1 <= tb_result1,
result2 <= tb_result2,
result3 <= tb_result3,
result4 <= tb_result4);
--STIMULUS PROCESS
stim_proc : process
begin
-- CODE HERE
end process;
end behavior;
As others have stated in the comments, you should provide some input yourself. What have you tried and why didn't it succeed? If you have hard time to find out what to try and how to start, you could begin by doing the following. And if you don't succeed, you can then edit your question or post a new one so the other members can help you.
Use a for loop to iterate over each and every possibility. Writing all the possible values to test by hand would be exhausting.
Because you have two inputs, use two nested for loops inside your process. One iterates the values for input a and the other one for b. Check here how a for loop is written.
Inside the loops, assign values to your signals tb_a and tb_b. The loop indices are integers, so you have to convert them to std_logic_vector type before assigning. Check here for a short tutorial about VHDL conversions.
Add some delay after each iteration with wait.
Print the output values for example to simulator console with report, or you can even use assert statement.

output is not connected to the rest of the design in rtl

This is my first time using rtl so I am having some issues which may be simple, but I have not been able to find anything that explains why this is happening and how to fix it. Currently when I create an rtl from my vhdl code, the ouputs are not shown to be connected to the rest of the design. The image below shows the outputs, not the rest of the design since it is pretty big.
The parts of my code which are relevant can be seen below:
`library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
entity FIFOClockOut is
port (
--Inputs
dataIn : IN std_logic_vector(7 downto 0); -- data input
clk : IN std_logic; -- clock input
EnableWr : IN std_logic; -- a value is being transmitted to the FIFO
clearMem : IN std_logic; -- clears the memory of the FIFO
resetOut : IN std_logic; -- resets the FIFO output counter
resetFull : IN std_logic; -- resets the the FIFO completely
--Outputs
MemNear : INOUT std_logic; -- the memory is almost out
FullMem : OUT std_logic; -- the memory is full in the FIFO
dataOut : OUT std_logic_vector(7 downto 0); -- data output
sel : INOUT std_logic_vector(2 downto 0); -- select output for mux
FinishedOut : OUT std_logic; -- the FIFO has finished sending out the data
clkOut : INOUT std_logic := '0' -- the clock that the output data is using
);
end FIFOClockOut;
architecture architecture_FIFOClockOut of FIFOClockOut is
-- signal, component etc. declarations
type ram_t is array (0 to 4095) of std_logic_vector(7 downto 0); -- The memory for the FIFO
signal ram: ram_t;
signal counterIn : integer; -- counter for input
signal counterOut : integer; -- counter for output
signal counterClock : std_logic_vector(2 downto 0); -- counter for clock
signal FullMemBuff : std_logic;
signal FinishedOutBuff: std_logic;
begin
process(clk)
begin
--there is some more code here which does not use dataOut
if (clk='1') then
if (FullMemBuff = '0') then
if (EnableWr = '1') then
ram(counterIn)<= dataIn;
counterIn <= counterIn + 1;
end if;
end if;
if(clkOut ='1') then
if (FinishedOutBuff = '0') then
counterClock <= counterClock + "1";
sel <= sel+"1";
end if;
if (counterClock = "111") then
if (FinishedOutBuff = '0') then
dataOut <= ram(counterOut);
counterOut <= counterOut+1;
if (counterIn <= (counterOut)) then
FinishedOutBuff <= '1';
sel<= "111";
dataOut <= "00000000";
end if;
else
dataOut <= "00000000";
sel <= "111";
end if;
end if;
end if;
end if;
end process;
end architecture_FIFOClockOut;
Thank you for the help. I am using Libero Polar Fire to code the vhdl and create the rtl. I have simulated the code and it works as expected and provides the correct output. Please ask questions if something is unclear or want more of the code.
So I fixed this by adding a buffer signal in the beginning of the code and setting the DataOut value equal to the DataOut buffer. Not quite sure why this worked, but it fixed it. If any one knows why I would love to know.

VHDL - Index out range even If I made concurrent checking using when-else

I'm implementing a register file where I wanna read asynchronously and write on the rising edge.
I made concurrent checks on the addresses and the writing occurs inside a process.
However, it always cause me a fatal error and I don't know why!
Here's my code if anyone could help and tell me how can I read asynchronously and write on rising edge
Thank you!
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity RegFile is
port(
outData1 : out std_logic_vector(15 downto 0);
outData2 : out std_logic_vector(15 downto 0);
inData : in std_logic_vector(15 downto 0);
writeEn : in std_logic;
reg1Sel : in std_logic_vector(2 downto 0);
reg2Sel : in std_logic_vector(2 downto 0);
writeRegSel : in std_logic_vector(2 downto 0);
clk : in std_logic
);
end RegFile;
architecture Register_File of RegFile is
type registerFile is array(0 to 5) of std_logic_vector(15 downto 0);
signal registers : registerFile;
signal reg1Address,reg2Address : integer;
signal reg1FinalAddressing,reg2FinalAddressing : std_logic_vector(2 downto 0);
begin
--Conversion of logic vector to unsigned integer
reg1Address <= to_integer(unsigned(reg1Sel));
reg2Address <= to_integer(unsigned(reg2Sel));
reg1FinalAddressing <= reg1Sel when (reg1Address<6 ) else
(others => '0');
reg2FinalAddressing <= reg2Sel when (reg2Address<6 ) else
(others => '0');
outData1 <= registers(to_integer(unsigned(reg1FinalAddressing)));
outData2 <= registers(to_integer(unsigned(reg2FinalAddressing)));
process (clk) is
begin
-- Reading from Registers 1 and 2
if rising_edge(clk) then
-- Writing to Register file Case Enabled
if writeEn = '1' then
registers(to_integer(unsigned(writeRegSel))) <= inData;
-- Case a value being written to register file, it will be out simultaneously if
-- the register was already selected. (The updated values are being released instantly).
if reg1Sel = writeRegSel then
outData1 <= inData;
end if;
if reg2Sel = writeRegSel then
outData2 <= inData;
end if;
end if;
end if;
end process;
end Register_File;

VHDL Filter not getting output for first values

I tried implementing a fir filter in VHDL but during the first three clocks I get no output and the error at 0 ps, Instance /filter_tb/uut/ : Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)..
Source file (I also have 2 other files for D Flip-Flops):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
entity filter is
port ( x: in STD_LOGIC_VECTOR(3 downto 0);
clk: in STD_LOGIC;
y: out STD_LOGIC_VECTOR(9 downto 0));
end filter;
architecture struct of filter is
type array1 is array (0 to 3) of STD_LOGIC_VECTOR(3 downto 0);
signal coef : array1 :=( "0001", "0011", "0010", "0001");
signal c0, c1, c2, c3: STD_LOGIC_VECTOR(7 downto 0):="00000000";
signal s0, s1, s2, s3: STD_LOGIC_VECTOR(3 downto 0) :="0000";
signal sum: STD_LOGIC_VECTOR(9 downto 0):="0000000000";
component DFF is
Port ( d : in STD_LOGIC_VECTOR(3 downto 0);
clk : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(3 downto 0));
end component;
component lDFF is
Port ( d : in STD_LOGIC_VECTOR(9 downto 0);
clk : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(9 downto 0));
end component;
begin
s0<=x;
c0<=x*coef(0);
DFF1: DFF port map(s0,clk,s1);
c1<=s1*coef(1);
DFF2: DFF port map(s1,clk,s2);
c2<=s2*coef(2);
DFF3: DFF port map(s2,clk,s3);
c3<=s3*coef(3);
sum<=("00" & c0+c1+c2+c3);
lDFF1: lDFF port map(sum,clk,y);
end struct;
Testbench:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use ieee.std_logic_unsigned.all;
ENTITY filter_tb IS
END filter_tb;
ARCHITECTURE behavior OF filter_tb IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT filter
PORT(
x : IN STD_LOGIC_VECTOR(3 downto 0);
clk : IN std_logic;
y : OUT STD_LOGIC_VECTOR(9 downto 0)
);
END COMPONENT;
--Inputs
signal x : STD_LOGIC_VECTOR(3 downto 0) := (others => '0');
signal clk : std_logic := '0';
--Outputs
signal y : STD_LOGIC_VECTOR(9 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: filter PORT MAP (
x => x,
clk => clk,
y => y
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc1: process
begin
x<="0001";
wait for 10ns;
x<="0011";
wait for 10ns;
x<="0010";
wait for 10ns;
--x<="0011";
end process;
END;
Output:
If anyonce could help, I'd appreciate it. I think it has something to do with the inital values of the signals c_i and s_i but I'm not too sure.
Your FIR filter contains flip-flops. These flip-flops have no reset input and so power up in an unknown state. You simulator models this by initialising the flip-flops' outputs to "UUUU" (as the are four bits wide). A 'U' std_logic value represents and uninitialised value.
So, your code behaves as you ought to expect. If you're not happy with that behaviour, you need to add a reset input and connect it to your flip-flops.
You have build a series of three register making up a cascade of registers.
You have not provided a reset so the register contents will be Unknown. You use the registers for calculations without any condition. Thus you arithmetic calculations will see the Unknown values and fail as you have seen.
The first (simplest) solution would be to add a reset. But that is not the best solution. You will no longer get warnings but the first three cycles of your output will be based on the register reset value not of your input signal.
If you have a big stream and don't care about some incorrect values in the first clock cycle you can live with that.
The really correct way would be to have a 'valid' signal transported along side your data. You only present the output data when there is a 'valid'. This is the standard method to process data through any pipeline hardware structure.
By the way: you normally do not build D-ffs yourself. The synthesizer will do that for you. You just use a clocked process and process the data vectors in it.
I have some questions. If I add a reset pin, when will I toggle it from 1 to 0? How can I create this circuit without explicitly using D-ffs?
You make a reset signal in the same way as you make your clock.
As to D-registers: they come out if you use the standard register VHDL code:
reg : process (clk,reset_n)
begin
// a-synchronous active low reset
if (reset_n='0') then
s0 <= "0000";
s1 <= "0000";
s2 <= "0000";
elsif (rising_edge(clk)) then
s0 <= x;
s1 <= s0;
s2 <= s1;
....
(Code entered as-is, not checked for syntax or typing errors)

VHDL code does not synthesize

I have written 2 state machines in my VHDL code. The simulation works fine, but the code does not synthesize. Any help would be appreciated. Here is my code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_arith.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
use IEEE.NUMERIC_STD.ALL;
entity pulse_width is
Port ( clk : in STD_LOGIC;
timer2:in std_logic;
input: in STD_LOGIC;
result: inout STD_LOGIC_VECTOR (15 downto 0);
SEL_LINE: IN STD_LOGIC_VECTOR(5 DOWNTO 0);
data_out: out STD_LOGIC_VECTOR (23 downto 0):=x"000000");
end pulse_width;
architecture Behavioral of pulse_width is
TYPE count_states is (s0,s0_dash,s1,s2,s3,s1_dash);
SIGNAL current_state, next_state : count_states := s0 ;
TYPE write_states is (ws0,ws0_dash,ws1,ws2,ws3,ws4);
SIGNAL current_state1, next_state1 : write_states := ws0 ;
TYPE index_array is ARRAY(integer range 0 to 65535) of std_logic_vector(15 downto 0);
SIGNAL mem: index_array;
SIGNAL count: std_logic_vector(15 downto 0):=x"0000";
SHARED VARIABLE j: integer:=0;
SHARED VARIABLE a,i: integer:=1;
SIGNAL flag,push_data,push_first,push_final,push_pulses,rw_first,rw_end: std_logic:='0';
SIGNAL y_clk_input ,y_clk_timer2, enable_count: std_logic:='0';
SIGNAL first,final: std_logic_vector(15 downto 0):= x"0001";
begin
-- Pulse width count
process (clk)
begin
if rising_edge(clk) then
current_state<=next_state;
current_state1<=next_state1;
end if;
end process;
process(input,SEL_LINE,current_state)
begin
------------------------------------------------------------------------
case current_state is
when s0 =>
if(input='1') then
next_state<=s1;
else
next_state<=s0;
end if;
when s1 =>
flag<='0';
if input='1' then
count <= count+ x"0001";
next_state<=s1_dash;
else
next_state<=s2;
end if;
when s1_dash =>
if input='1' then
count <= count+ x"0001";
next_state<=s1;
else
next_state<=s2;
end if;
when s2 =>
result <= count;
next_state<=s3;
when s3=>
count <= x"0000";
next_state<=s0;
enable_count<='0';
when others =>
next_state<=s0;
end case;
--------------------------------------------------------------------------
case current_state1 is
when ws0 =>
if (result>x"0000") then
next_state1<=ws1;
else
next_state1<=ws0_dash;
end if;
when ws0_dash =>
if (result>x"0000") then
next_state1<=ws1;
else
next_state1<=ws0;
end if;
when ws1=>
if rw_first='1' and rw_end='1' then
next_state1<=ws0;
else
mem(a) <= result;
a:=a+1;
final<=final+x"0001";
next_state1<=ws2;
end if;
when ws2 =>
next_state1<=ws0;
result<=x"0000";
when others =>
next_state1<=ws0;
end case;
end process;
I eventually need to implement three state machines.
The math you're trying to do in the asynchronous state logic is not registered and won't synthesize well. You need to re-arrange your state logic so statements like:
count <= count+ x"0001";
...
final<=final+x"0001";
...are synchronous and not 'free running' in an asynchronous loop.
The problem is that you read and write the same signals in one combinational process.
Either put everything in one clocked (synchronous) process
Or: use explicit registers: count_next <= count + x"0001";
Not related to your error, but still worth paying attention to:
You have a ton of unused signals and shared variables:
push_data,push_first,push_final,push_pulses, y_clk_input ,y_clk_timer2, first, i,j
This is confusing for anybody trying to read your code. 1
The packages STD_LOGIC_arith and STD_LOGIC_unsigned are deprecated

Resources