Why my VHDL code for generating a VGA signal doesn't work - vhdl

I have been going crazy trying to make it work but nothing been on this for the past 6 hours and still didn't solve it :/
so this the top module
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Test is
Port ( CLKI : in STD_LOGIC;
HSO : out STD_LOGIC;
VSO : out STD_LOGIC;
RO,GO,BO : out STD_LOGIC);
end Test;
architecture Behavioral of Test is
component CLK_25Mhz_Divider
Port ( CLK : in STD_LOGIC;
CLK_OUT : out STD_LOGIC);
end component;
component VGA_Sync
Port ( CLK : in STD_LOGIC;
HS : out STD_LOGIC;
VS : out STD_LOGIC;
R,G,B : out STD_LOGIC);
end component;
signal CLKBE: STD_LOGIC;
begin
CLK_Divider_1: CLK_25Mhz_Divider port map ( CLK => CLKI,
CLK_OUT => CLKBE);
VGA_S1: VGA_Sync port map ( CLK => CLKBE,
HS => HSO,
VS => VSO,
R => RO,
G => GO,
B => BO );
end Behavioral;
the clock divider
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity CLK_25MHz_Divider is
Port ( CLK : in STD_LOGIC;
CLK_OUT : out STD_LOGIC);
end CLK_25MHz_Divider;
architecture Behavioral of CLK_25MHz_Divider is
BEGIN
PROCESS(CLK)
VARIABLE COUNT : INTEGER:=0;
VARIABLE TEMP : STD_LOGIC:='0';
BEGIN
IF RISING_EDGE(CLK)THEN
COUNT:=COUNT+1;
IF COUNT=2 THEN
TEMP:=NOT TEMP;
COUNT:=0;
END IF;
END IF;
CLK_OUT<=TEMP;
END PROCESS;
end Behavioral;
The VGA signal generation module
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity VGA_Sync is
Port ( CLK : in STD_LOGIC;
HS : out STD_LOGIC;
VS : out STD_LOGIC;
R,G,B : out STD_LOGIC);
end VGA_Sync;
architecture Behavioral of VGA_Sync is
begin
process(CLK)
Variable countH : Integer := 0;
Variable countV : Integer := 0;
begin
if (CLK'EVENT and CLK = '1') then
if countH < 800 then
countH := countH + 1;
else
countH := 0;
if countV < 500 then
countV := countV + 1;
else
countV := 0;
end if;
end if;
if countH >= 16 and countH < 112 then
HS <= '0';
else
HS <= '1';
end if;
if countV >= 10 and countV < 12 then
VS <= '0';
else
VS <= '1';
end if;
if (countH < 160) or (countV < 45) then
R <= '0';
G <= '0';
B <= '0';
else
R <= '1';
G <= '0';
B <= '1';
end if;
end if;
end process;
end Behavioral;
so tell me your thoughts on what is wrong with the code

Because you haven't actually describe the problem and because I had a testbench for a 25 MHz clocked vga generator that only required changing the type for r, g and b, I ran you sync_vga against the testbench:
library ieee;
use ieee.std_logic_1164.all;
entity vga_sync_tb is
end entity;
architecture foo of vga_sync_tb is
signal clk: std_logic := '0';
signal hs: std_logic;
signal vs: std_logic;
signal r,g,b: std_logic;
begin
DUT:
entity work.vga_sync
port map (
clk => clk,
hs => hs,
vs => vs,
r => r,
g => g,
b => b
);
CLOCK:
process
begin
wait for 20 ns; -- clock period 25 MHz = 40 ns;
clk <= not clk;
if now > 20 ms then -- one frame time plus a bit
wait;
end if;
end process;
end architecture;
It gave a vertical sync rate around 60 Hz:
Zooming in and measuring between two HS edges shows a horizontal rate of around 31.17 KHz.
You have horizontal and vertical blanking intervals and your R, G, and B does what your code says.
That sort of leaves the clock divider or something platform related.
Because a testbench for the clock is simple:
library ieee;
use ieee.std_logic_1164.all;
entity clock_tb is
end entity;
architecture foo of clock_tb is
signal clk: std_logic := '0';
signal clk25: std_logic;
begin
DUT:
entity work.clk_25mhz_divider
port map (
clk => clk,
clk_out => clk25
);
CLOCK:
process
begin
wait for 10 ns; -- half the period of 50 MHz
clk <= not clk;
if now > 130 ns then
wait;
end if;
end process;
end architecture;
It demonstrates Martin Zabel's answer:
That your divide by two actually divides by four. giving a period of 80 ns (12.5 MHz).
This demonstrates the usefulness of simulation and in simulation it can also be helpful to use signals instead of variables which have no history. Variables don't have a projected output waveform and he simulator has to attach extra code to display them in a waveform.
The simulation performance increase using variables instead of signals is traded for the ability to display them and there is no interesting distinction in synthesis.

From comments below question:
at that resolution i should use 25Mhz so i using the onboard clock
that's 50 Mhz and dividing it using the Clock divider module. –
Mostafa
Your clock divider divides the input frequency by 4 instead of 2. You toggle TEMP every two cycles of CLK which is CLKI of the top module. So a full cycle of CLK_OUT takes 4 cycles of the input clock.
To divide by two, you must toggle TEMP every clock cycle of the input clock:
architecture Behavioral of CLK_25MHz_Divider is
BEGIN
PROCESS(CLK)
VARIABLE TEMP : STD_LOGIC:='0';
BEGIN
IF RISING_EDGE(CLK)THEN
TEMP:=NOT TEMP;
END IF;
CLK_OUT<=TEMP;
END PROCESS;
end Behavioral;
Starting with TEMP = '0', it toggles to '1' at the first rising edge of CLK. At the second rising edge, TEMP toggles to '0', and at the third rising edge back to '1'. The duration between the first and third rising-edge of the 50 MHz input clock is 40 ns, which makes a frequency of 25 MHz for the output clock.

Related

I’m new to coding in VHDL and don’t understand why my code will not show an output when simulating on a VWF file

My code will not simulate an output when running the VWF file.
I have tried changing the code several different time and don't really understand what I'm doing wrong.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Counter_JM is
Port (
up_down : in std_logic;
LED : out std_logic;
Q : Buffer integer Range 0 to 7);
end Counter_JM;
architecture archi of Counter_JM is
Begin
-- up/down counter
process (up_down)
begin
if (Q=7) then
Q<=0;
end if;
if (up_down = '1') then
Q <= Q + 1;
else
Q<=0;
end if;
if (Q=0 or Q=1) then
LED <= '0';
else
LED <= '1';
end if;
end process;
end archi;
The LED output should show high for 4 cycles and low for 2 on the VWF file
I don't know why you use up_down. But as Oldfart said, you don't have a clock. I have simplified and modified your code (it works for me (in modelsim):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Counter_JM is
Port (
clk: in std_logic;
up_down : in std_logic;
LED : out std_logic
);
end Counter_JM;
architecture archi of Counter_JM is
Begin
process (clk)
variable Q: integer range 0 to 7;
begin
if rising_edge(clk) then
-- up/down counter
Q := Q + 1;
if Q=1 or Q=2 then
LED <= '0';
else
LED <= '1';
end if;
if Q = 7 then
Q := 0;
end if;
end if;
end process;
end archi;
and also created/generated a simple testbench here :
`-- Testbench automatically generated online
-- at http://vhdl.lapinoo.net
-- Generation date : 7.6.2019 11:22:53 GMT
library ieee;
use ieee.std_logic_1164.all;
entity tb_Counter_JM is
end tb_Counter_JM;
architecture tb of tb_Counter_JM is
component Counter_JM
port (clk : in std_logic;
up_down : in std_logic;
LED : out std_logic);
end component;
signal clk : std_logic;
signal up_down : std_logic;
signal LED : std_logic;
constant TbPeriod : time := 1000 ns; -- EDIT Put right period here
signal TbClock : std_logic := '0';
signal TbSimEnded : std_logic := '0';
begin
dut : Counter_JM
port map (clk => clk,
up_down => up_down,
LED => LED);
-- Clock generation
TbClock <= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0';
-- EDIT: Check that clk is really your main clock signal
clk <= TbClock;
stimuli : process
begin
-- EDIT Adapt initialization as needed
up_down <= '0';
-- EDIT Add stimuli here
wait for 100 * TbPeriod;
-- Stop the clock and hence terminate the simulation
TbSimEnded <= '1';
wait;
end process;
end tb;
-- Configuration block below is required by some simulators. Usually no need to edit.
configuration cfg_tb_Counter_JM of tb_Counter_JM is
for tb
end for;
end cfg_tb_Counter_JM;`

How to find frequency of a clock divider ?

Supposing i have on my board a 100Mhz clock and the following clock divider:
entity div is
port(clk:in std_logic;
clk_out:out std_logic);
architecture ar of div is
begin
process(clk)
variable aux:integer := 0;
variable aux2:std_logic := '0';
begin
if clk = '1' and clk'event then
aux := aux + 1;
if aux = 1600500 and aux2='0' then
aux = 0;
aux2 = 1;
end if;
if aux = 1600500 and aux2 ='1' then
aux = 0;
aux2 = 1;
end if;
end if;
clk_out <= aux2;
end process;
end;
What will be the frequency of the new clock(clk_out) ?
Clock dividers come in many flavors.
If you are looking at high speed clocks, for instance when using dual-data rate (DDR) memory, you actually want to use the FPGA's clock manager. E.g. Xilinx Digital Clock Manager (DCM). These provide a very stable, edge synchronous clock output.
For lower speed clocks, you could use the divider you suggest. However, these also come in multiple flavors. If the division ratio is integer, you can use the simple counter like you do. For this next example, the clock divider will always divide the input frequency by 2 (e.g. 50 MHz-> 25 MHz) and then further divide by the ratio set (e.g. 25/3 = 8 1/3 MHz)
library ieee;
use ieee.std_logic_1164.all;
entity simp_clk_div is
generic(
half_clk_div_ratio : positive);
port(
input_clk : in std_logic;
output_clk : out std_logic);
end entity;
architecture rtl of simp_clk_div is
constant clk_div_cnt : natural := half_clk_div_ratio - 1;
signal cnt : natural := clk_div_cnt;
signal output_clk_i : std_logic := '0';
begin
divide : process(input_clk) begin
if rising_edge(input_clk) then
if cnt = 0 then
cnt <= clk_div_cnt;
output_clk_i <= not output_clk_i;
else
cnt <= cnt - 1;
end if;
end if;
end process;
output_clk <= output_clk_i;
end architecture;
entity simp_clk_div_tb is end entity;
library ieee;
architecture behavior of simp_clk_div_tb is
use ieee.std_logic_1164.all;
signal input_clk, output_clk : std_logic;
begin
DUT : entity work.simp_clk_div
generic map(
clk_div_ratio => 3)
port map(
input_clk => input_clk,
output_clk => output_clk);
clk_stim : process begin
input_clk <= '0', '1' after 1 ns;
wait for 2 ns;
if (now > 200 ns) then wait; end if;
end process;
end architecture;
If you want more freedom, e.g. convert 50MHz to 3 MHz, you can use a fractional clock divider. However, this component requires a lot more resources. Plus, there's a lot of jitter on the clock output, in the form of unequal length clock pulses. But that's usually not a big problem with low speed clocks.
library ieee;
use ieee.std_logic_1164.all;
entity frac_clk_div is
generic(
input_freq : positive;
output_freq : positive);
port(
input_clk : in std_logic;
output_clk : out std_logic);
end entity;
architecture rtl of frac_clk_div is
constant cnt_sub : positive := output_freq*2;
signal cnt : natural := input_freq;
signal output_clk_i : std_logic := '0';
begin
divide : process(input_clk) begin
if rising_edge(input_clk) then
if cnt < cnt_sub then
cnt <= input_freq - (cnt_sub - cnt);
output_clk_i <= not output_clk_i;
else
cnt <= cnt - cnt_sub;
end if;
end if;
end process;
output_clk <= output_clk_i;
end architecture;
entity frac_clk_div_tb is end entity;
library ieee;
architecture behavior of frac_clk_div_tb is
use ieee.std_logic_1164.all;
signal input_clk, output_clk : std_logic;
begin
DUT : entity work.frac_clk_div
generic map(
input_freq => 50_000_000,
output_freq => 3_000_000)
port map(
input_clk => input_clk,
output_clk => output_clk);
clk_stim : process begin
input_clk <= '0', '1' after 1 ns;
wait for 2 ns;
if (now > 200 ns) then wait; end if;
end process;
end architecture;

No Output From Entity in ModelSim Simulator - VHDL

I have written a simple entity in VHDL to blink an LED and am trying to simulate it in ModelSim but am getting no transitions on the output.
Here is my HDL file for the LED_Blink entity:
Library IEEE;
use IEEE.Std_logic_1164.all;
entity LED_Blink is
generic (
g_SYSTEM_CLOCK_PERIOD : in time := 10 ns; -- 100 MHz clock period
g_LED_ON_TIME : in time := 1 sec
);
port(
system_clock : in Std_logic;
reset_fpga_L : in Std_logic;
led_out : out Std_logic
);
end entity LED_Blink;
architecture RTL of LED_Blink is
signal led_state : Std_logic;
constant COUNTER_RELOAD_VAL : natural := g_LED_ON_TIME/g_SYSTEM_CLOCK_PERIOD;
begin
process(reset_fpga_L, system_clock)
variable counter : natural range 0 to COUNTER_RELOAD_VAL := COUNTER_RELOAD_VAL;
begin
if reset_fpga_L = '0' then
counter := COUNTER_RELOAD_VAL;
led_state <= '0';
elsif rising_edge(system_clock) then
if counter = 0 then
led_state <= not led_state;
counter := COUNTER_RELOAD_VAL;
else
counter := counter - 1;
end if;
end if;
led_out <= led_state;
end process;
end architecture RTL;
And here is my test-bench:
Library IEEE;
use IEEE.Std_logic_1164.all;
entity LED_Blink_TB is
end entity LED_Blink_TB;
architecture RTL of LED_Blink_TB is
signal reset_fpga_L : Std_logic := '0';
signal system_clock : Std_logic := '0';
signal led_out : Std_logic := '0';
begin
G1: entity work.LED_Blink(RTL) port map(reset_fpga_L, system_clock, led_out);
CLK: process
begin
while now <= 5 sec loop
system_clock <= not system_clock;
wait for 5 ns;
end loop;
wait;
end process CLK;
STIM: process
begin
reset_fpga_L <= '0';
wait for 100 ns;
reset_fpga_L <= '1';
wait for 4 sec;
reset_fpga_L <= '0';
wait for 50 ns;
reset_fpga_L <= '1';
wait;
end process STIM;
end architecture RTL;
I can't figure out why I'm not seeing any transitions on led_out when I run my test-bench in the simulator. I've taken care to add the waves for system_clock, reset_fpga_L, and led_out to the trace view. Do you see anything in my code that might be an issue? Thanks for your help.
A second form of the testbench can be used make generation of inputs to LED_Blink depend on the values supplied as generics:
library ieee;
use ieee.std_logic_1164.all;
entity led_blink_tb is
end entity;
architecture foo of led_blink_tb is
constant CLK_PERIOD: time := 100 ms;
constant LED_ON: time := 500 ms;
signal clk: std_logic := '0';
signal reset_n: std_logic;
signal led: std_logic;
begin
DUT:
entity work.led_blink
generic map ( CLK_PERIOD, LED_ON)
port map (
system_clock => clk,
reset_fpga_l => reset_n,
led_out => led
);
CLOCK:
process
begin
wait for CLK_PERIOD/2;
clk <= not clk;
if now > 2.5 sec then
wait;
end if;
end process;
STIMULI:
process
begin
reset_n <= '0';
wait for CLK_PERIOD * 2;
reset_n <= '1';
wait;
end process;
end architecture;
The idea, both the testbench and the model depend on constants supplied as generics making changing the parameters require less work.
Also note the association list in the port map uses named association.
If we take a look at the original testbench port map:
G1: entity work.LED_Blink(RTL) port map(reset_fpga_L, system_clock, led_out);
We see that the first positional association to the formal system_clock is associated with the actual reset_fpga_L while the second positional association representing formal reset_fpga_L is associated with the actual system_clock.
The two actual associations are in reversed order.

VHDL - Non-regular clock pattern generation

My question is relatively simple: is it possible in VHDL to generate a clock with a specific, non-regular pattern without using a process and the after keyword?
In other words, if I have a process that generates a clock like this:
process(Start)
begin
if Start = '0' then
clock <= '0';
else if Start = '1' then
clock <= '0',
'1' after 25 ns,
'0' after 35 ns,
'1' after 50 ns,
'0' after 75 ns,
'1' after 105 ns,
...
end process;
can I get the same output using (for istance) some components, like some sort of delays?
I know that probably it wouldn't be of any use, but my professor asked us to replicate this exercise using structural VHDL. I just need to simulate it, I don't need to make it synthesizable.
Imagine a counter that counts 5 ns period clocks and an initial value for clock of '0' and the counter of (others => '0'). at count = 5 (25 ns), 7 (35 ns), 10 (50 ns) a combinatorial signal toggle goes true ('1'),... with others toggle set to false ('0'). If the clock is continuous you pick a count to restore the count to all '0's. The toggle signal is an enable for a D Flip Flop (clock is the output) with it's Qnot connected to D run off the high speed clock (supplied externally from a testbench). The size of count is determined last even in 5 ns increments.
Well we'd adjust the count comparison values down by one to compensate for the D Flip Flop and it would look something like this structurally:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity counter is -- counts 0 to 31
port (
clk: in std_logic;
count: out std_logic_vector (4 downto 0);
zero: out std_logic
);
end entity;
architecture foo of counter is
signal cnt: unsigned (count'range) := (others => '0'); -- start at zero
constant period: integer := 31; -- 32 is the period of the the sequence
begin
process (clk)
begin
if rising_edge (clk) then
if cnt < period then
cnt <= cnt + 1;
else
cnt <= (others => '0');
end if;
end if;
end process;
count <= std_logic_vector(cnt);
zero <= '1' when cnt = 0 else
'0';
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity d_flip_flop is -- has enable
port (
resetn: in std_logic;
clk: in std_logic;
en: in std_logic;
d: in std_logic;
q: out std_logic
);
end entity;
architecture foo of d_flip_flop is
signal qn: std_logic := '1';
begin
process (resetn, clk)
begin
if resetn = '0' then
qn <= '1';
elsif rising_edge (clk) and en = '1' then
qn <= not d;
end if;
end process;
q <= not qn;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity inv is
port (
a: in std_logic;
o: out std_logic
);
end entity;
architecture foo of inv is
begin
o <= not a;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity toggle_pla_rom is
port (
count: in std_logic_vector (4 downto 0);
toggle: out std_logic
);
end entity;
architecture foo of toggle_pla_rom is
type rom_array is array (0 to 31) of std_logic; -- fully constrained
constant rom: rom_array := ( 4 | 6 | 9 | 14 | 20 => '1', others => '0');
begin
toggle <= rom(to_integer(unsigned(count)));
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity clock_gen is
port (
clk: in std_logic;
clock: out std_logic
);
end entity;
architecture foo of clock_gen is
signal toggle: std_logic;
signal resetn: std_logic;
signal din: std_logic;
signal count: std_logic_vector (4 downto 0);
signal q: std_logic;
signal nq: std_logic;
signal zero: std_logic;
begin
CNTR:
entity work.counter
port map (
clk => clk,
count => count,
zero => zero
);
DIN_INV:
entity work.inv
port map (
a => q,
o => nq
);
ZERO_INV:
entity work.inv
port map (
a => zero,
o => resetn
);
DFF:
entity work.d_flip_flop
port map (
resetn => resetn,
clk => clk,
en => toggle,
d => nq,
q => q
);
TOGGLE_LUT:
entity work. toggle_pla_rom
port map (
count => count,
toggle => toggle
);
clock <= q;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity clock_gen_tb is
end entity;
architecture foo of clock_gen_tb is
signal clk: std_logic := '1'; -- clk has 5 ns period
signal clock: std_logic;
begin
CLOCKGEN:
entity work.clock_gen
port map (
clk => clk,
clock => clock
);
CLKGEN:
process
begin
wait for 2.5 ns;
clk <= not clk;
if now > 300 ns then
wait;
end if;
end process;
MONITOR:
process
begin
wait for 0 ns;
wait until clock'event;
report "clock = " & std_logic'image(clock);
end process;
end architecture;
The look up table used to determine the count values where a toggle occurs could be replaced with and/ors, etc. for true primitive level description.
The counter wraps, which is easy to cure (it could stop instead for instance). Because you didn't specify any further edge events it's tailored to the size needed for the number of edge events you did specify. The size of the counter and the number of events can be scaled up.
When run the clock_gen_tb testbench reports clock events and shows that it meets your specification:
logarithmic_clock.vhdl:188:9:#0ms:(report note): clock = '0'
logarithmic_clock.vhdl:188:9:#25ns:(report note): clock = '1'
logarithmic_clock.vhdl:188:9:#35ns:(report note): clock = '0'
logarithmic_clock.vhdl:188:9:#50ns:(report note): clock = '1'
logarithmic_clock.vhdl:188:9:#75ns:(report note): clock = '0'
logarithmic_clock.vhdl:188:9:#105ns:(report note): clock = '1'
logarithmic_clock.vhdl:188:9:#160ns:(report note): clock = '0'
logarithmic_clock.vhdl:188:9:#185ns:(report note): clock = '1'
logarithmic_clock.vhdl:188:9:#195ns:(report note): clock = '0'
logarithmic_clock.vhdl:188:9:#210ns:(report note): clock = '1'
logarithmic_clock.vhdl:188:9:#235ns:(report note): clock = '0'
logarithmic_clock.vhdl:188:9:#265ns:(report note): clock = '1'
The first 6 times match your specification.
A waveform display shows the counts, toggles, zero (representing the flip flop reset) and clock:
One thing this example points out is that all VHDL structural models capable of simulation are described behaviorally.
ok, you could try to use others keywords to generate a delay like wait for and loop inside of process block. This is an example:
clock_gen: process
constant duty_cycle : real := 0.40
constant period : time := 100 ns ;
constant clk_high : time := duty_cycle * period ;
begin
loop
clk <= '0';
wait for period - clk_high; -- clock low time
clk <= '1';
wait for clk_high; -- clock high time
end loop;
end process;
end behavioral;
This is a clock with a variable duty cycle and period.
Creating a clock without a process doesn't make any sense (structural VHDL doesn't provide any kind of synchronization), however you can simulate the special clock pattern by applying the right logic to some regular clock signals provided by a testbench for example.
For example consider having an input of 2 clocks (one start at 0, the other at 1), this will give you the possibility to implement a 2 state machine, think of it like a counter from based on the periodicity of your source clock..
You can also have 2 clocks sources where the periodicity of the second clock is twice the first one to get a 2^2 state machine, in this case you are free to start both clocks at low level (0).
This way you can implement the needed pattern without using any process (no behavioral VHDL is used).

Realizing Top Level Entity in Testbench using VHDL

I'm a newbie in VHDL and hardware world.
I'm trying to make a Count&Compare example using Top Level Hierarchy and test it with testbench and see the results on ISIM.
Here is my block diagram sketch:
So I end up these 3 vhd source files:
Counter.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Count_src is
Port ( CLK : in STD_LOGIC;
Reset : in STD_LOGIC;
S : out STD_LOGIC_VECTOR (3 downto 0));
end Count_src;
architecture Behavioral of Count_src is
signal count : STD_LOGIC_VECTOR (3 downto 0);
begin
process (Reset, CLK)
begin
if Reset = '1' then -- Active high reset
count <= "0000"; -- Clear count to 0
elsif (rising_edge(CLK)) then -- Positive edge
count <= count + "0001"; -- increment count
end if;
end process;
S <= count; -- Export count
end Behavioral;
Compare
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Compare_src is
Port ( A : in STD_LOGIC_VECTOR (3 downto 0);
B : in STD_LOGIC_VECTOR (3 downto 0);
S : out STD_LOGIC);
end Compare_src;
architecture Behavioral of Compare_src is
begin
S <= '1' when (A = B) else -- Test if A and B are same
'0'; -- Set when S is different
end Behavioral;
CountCompare (Top Level)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity CountCompare_src is
Port ( Clock : in STD_LOGIC;
Reset : in STD_LOGIC;
Value : in STD_LOGIC_VECTOR (3 downto 0);
Flag : out STD_LOGIC);
end CountCompare_src;
architecture Behavioral of CountCompare_src is
-- COMPONENT DECLERATIONS
component counter is
port ( CLK : in std_logic;
Reset : in std_logic;
S : out std_logic_vector(3 downto 0)
);
end component;
component compare is
port (A : in std_logic_vector(3 downto 0);
B : in std_logic_vector(3 downto 0);
S : out std_logic
);
end component;
-- Component Spesification and Binding
for all : counter use entity work.Count_src(behavioral);
for all : compare use entity work.Compare_src(behavioral);
-- Internal Wires
signal count_out : std_logic_vector(3 downto 0);
begin
-- Component instantiation
C1: counter PORT MAP ( Reset => Reset,
CLK => Clock,
S => count_out
);
C2: compare PORT MAP ( A => count_out,
B => Value,
S => Flag
);
end Behavioral;
To test the design I wrote a testbench as follows:
TestBench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY TopLevelTester_tb IS
END TopLevelTester_tb;
ARCHITECTURE behavior OF TopLevelTester_tb IS
--Input and Output definitions.
signal Clock : std_logic := '0';
signal Reset : std_logic := '0';
signal Value : std_logic_vector(3 downto 0) := "1000";
signal Flag : std_logic;
-- Clock period definitions
constant clk_period : time := 1 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: entity work.CountCompare_src PORT MAP
(
Clock => Clock,
Reset => Reset,
Value => Value
);
proc: process
begin
Clock <= '0';
wait for clk_period/2;
Clock <= '1';
wait for clk_period/2;
end process;
END;
When I simulate behavioral model, the ISIM pops up, but I see no changes on the Compare Flag. Here is the ss of the ISIM:
What am I missing here? Why does'nt the Flag change?
My best regards.
You have two problems, both in your testbench.
The first is that you never reset count in the counter, it will always be 'U's or 'X's (after you increment it).
The second is that the directly entity instantiation in the testbench is missing an association for the formal flag output to the actual flag signal:
begin
uut:
entity work.countcompare_src
port map (
clock => clock,
reset => reset,
value => value,
flag => flag
);
proc:
process
begin
clock <= '0';
wait for clk_period/2;
clock <= '1';
wait for clk_period/2;
if now > 20 ns then
wait;
end if;
end process;
stimulus:
process
begin
wait for 1 ns;
reset <= '1';
wait for 1 ns;
reset <= '0';
wait;
end process;
Fix those two things and you get:

Resources