* 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 |