* blink should display incrementing binary numbers at LED1-LED8 of the GateMate FPGA Starter Kit. * Increment is done with circa 9.5 Hzblink_with_pll
@ -0,0 +1,52 @@ | |||||
-- This design should display incrementing binary numbers | |||||
-- at LED1-LED8 of the GateMate FPGA Starter Kit. | |||||
library ieee ; | |||||
use ieee.std_logic_1164.all; | |||||
use ieee.numeric_std.all; | |||||
entity blink is | |||||
port ( | |||||
clk_i : in std_logic; -- 10 MHz clock | |||||
rst_n_i : in std_logic; -- SW3 button | |||||
led_n_o : out std_logic_vector(7 downto 0) -- LED1..LED8 | |||||
); | |||||
end entity blink; | |||||
architecture rtl of blink is | |||||
signal s_clk_cnt : unsigned(19 downto 0); | |||||
signal s_clk_en : boolean; | |||||
signal s_led : unsigned(led_n_o'range); | |||||
begin | |||||
process (clk_i, rst_n_i) is | |||||
begin | |||||
if (not rst_n_i) then | |||||
s_clk_cnt <= (others => '0'); | |||||
elsif (rising_edge(clk_i)) then | |||||
s_clk_cnt <= s_clk_cnt + 1; | |||||
end if; | |||||
end process; | |||||
s_clk_en <= s_clk_cnt = (s_clk_cnt'range => '1'); | |||||
process (clk_i, rst_n_i) is | |||||
begin | |||||
if (not rst_n_i) then | |||||
s_led <= (others => '0'); | |||||
elsif (rising_edge(clk_i)) then | |||||
if (s_clk_en) then | |||||
s_led <= s_led + 1; | |||||
end if; | |||||
end if; | |||||
end process; | |||||
led_n_o <= not std_logic_vector(s_led); | |||||
end architecture; |
@ -0,0 +1,26 @@ | |||||
DESIGN_NAME := blink | |||||
RTL_SRC := ../rtl/${DESIGN_NAME}.vhd | |||||
SIM_SRC := tb_${DESIGN_NAME}.vhd | |||||
VHD_STD := 08 | |||||
.PHONY: all compile sim clean | |||||
all: sim | |||||
compile: tb_${DESIGN_NAME} | |||||
tb_${DESIGN_NAME}: ${RTL_SRC} ${SIM_SRC} | work | |||||
@echo "Analyze testbench & design ..." | |||||
ghdl -a --std=${VHD_STD} -fpsl --workdir=work ${RTL_SRC} ${SIM_SRC} | |||||
@echo "Elaborate testbench & design ..." | |||||
ghdl -e --std=${VHD_STD} -fpsl --workdir=work $@ | |||||
sim: tb_${DESIGN_NAME} | |||||
@echo "Run testbench ..." | |||||
ghdl -r tb_${DESIGN_NAME} --assert-level=error | |||||
work: | |||||
mkdir $@ | |||||
clean: | |||||
@echo "Cleaning simulation files ..." | |||||
rm -rf tb_${DESIGN_NAME} *.o *.json work/ |
@ -0,0 +1,45 @@ | |||||
library ieee ; | |||||
use ieee.std_logic_1164.all; | |||||
use ieee.numeric_std.all; | |||||
use std.env.all; | |||||
entity tb_blink is | |||||
end entity tb_blink; | |||||
architecture sim of tb_blink is | |||||
signal s_clk : std_logic := '1'; | |||||
signal s_rst_n : std_logic := '0'; | |||||
signal s_led_n : std_logic_vector(7 downto 0); | |||||
begin | |||||
dut : entity work.blink | |||||
port map ( | |||||
clk_i => s_clk, | |||||
rst_n_i => s_rst_n, | |||||
led_n_o => s_led_n | |||||
); | |||||
s_rst_n <= '1' after 1.2 us; | |||||
s_clk <= not s_clk after 500 ns; | |||||
-- Let's test the first 8 values of LED output | |||||
process is | |||||
begin | |||||
wait until s_rst_n; | |||||
wait until rising_edge(s_clk); | |||||
for i in 0 to 7 loop | |||||
report "LED: " & to_hstring(not s_led_n); | |||||
assert to_integer(unsigned(not s_led_n)) = i | |||||
report "LED error, got 0x" & to_hstring(s_led_n) & ", expected 0x" & to_hstring(to_unsigned(255-i, 8)) | |||||
severity failure; | |||||
wait until s_led_n'event; | |||||
end loop; | |||||
stop(0); | |||||
end process; | |||||
end architecture; |
@ -0,0 +1,21 @@ | |||||
DESIGN_NAME := blink | |||||
SRC_FILES := ../rtl/blink.vhd | |||||
VHD_STD := 08 | |||||
.PHONY: all syn | |||||
all: ${DESIGN_NAME}_synth.vhd syn | |||||
syn: ${DESIGN_NAME}.v | |||||
${DESIGN_NAME}.o: ${SRC_FILES} | |||||
ghdl -a --std=${VHD_STD} ${SRC_FILES} | |||||
${DESIGN_NAME}_synth.vhd: ${SRC_FILES} | |||||
ghdl --synth --std=$(VHD_STD) ${SRC_FILES} -e ${DESIGN_NAME} > $@ | |||||
${DESIGN_NAME}.v: ${DESIGN_NAME}.o | |||||
yosys -m ghdl -p 'ghdl --std=${VHD_STD} --no-formal ${DESIGN_NAME}; synth_gatemate -nomx8 -vlog $@' | |||||
clean : | |||||
echo "# Cleaning files" | |||||
rm -f *.o work*.cf ${DESIGN_NAME}.v ${DESIGN_NAME}_synth.vhd |