Skip to content

Commit 9c09e8b

Browse files
committed
Some bugfix, added SPI loopback example.
1 parent 353f40b commit 9c09e8b

10 files changed

+710
-107
lines changed

README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ The SPI master and SPI slave controllers have been simulated.
1010

1111
CONTROLLER | LE (LUT) | FF | BRAM | Fmax
1212
:---:|:---:|:---:|:---:|:---:
13-
SPI master | 36 | 25 | 0 | 346.9 MHz
14-
SPI slave | 26 | 19 | 0 | 438.7 MHz
13+
SPI master | 39 | 26 | 0 | 264.7 MHz
14+
SPI slave | 23 | 16 | 0 | 359.7 MHz
1515

1616
*Synthesis have been performed using Quartus Prime 16.1 Lite Edition for FPGA Altera Cyclone IV with these settings: CLK_FREQ = 50 MHz, SCLK_FREQ = 5 MHz, SLAVE_COUNT = 1.*
1717

@@ -27,8 +27,8 @@ Please read [LICENSE file](LICENSE).
2727

2828
Generic name | Type | Default value | Generic description
2929
---|:---:|:---:|:---
30-
CLK_FREQ | natural | 50 | System clock frequency in MHz.
31-
SCLK_FREQ | natural | 5 | SPI clock frequency in MHz (must be < CLK_FREQ/9).
30+
CLK_FREQ | natural | 50 | System clock frequency in Hz.
31+
SCLK_FREQ | natural | 5 | Set SPI clock frequency in Hz (condition: SCLK_FREQ <= CLK_FREQ/10).
3232
SLAVE_COUNT | natural | 1 | Count of SPI slave controllers.
3333

3434
## Table of inputs and outputs ports:

example/comp/btn_debounce.vhd

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
--------------------------------------------------------------------------------
2+
-- PROJECT: FPGA MISC
3+
--------------------------------------------------------------------------------
4+
-- NAME: BTN_DEBOUNCE
5+
-- AUTHORS: Jakub Cabal <[email protected]>
6+
-- LICENSE: The MIT License
7+
-- WEBSITE: https://github.com/jakubcabal/fpga-misc
8+
--------------------------------------------------------------------------------
9+
10+
library IEEE;
11+
use IEEE.STD_LOGIC_1164.ALL;
12+
use IEEE.NUMERIC_STD.ALL;
13+
14+
entity BTN_DEBOUNCE is
15+
Port (
16+
CLK : in std_logic; -- system clock
17+
CLK_EN_1K : in std_logic; -- clock enable 1 KHz
18+
ASYNC_RST : in std_logic; -- asynchrounous reset
19+
BTN_RAW : in std_logic; -- button raw signal
20+
BTN_DEB : out std_logic; -- button debounce signal
21+
BTN_DEB_EN : out std_logic -- button debounce rising edge enable
22+
);
23+
end BTN_DEBOUNCE;
24+
25+
architecture RTL of BTN_DEBOUNCE is
26+
27+
signal btn_raw_shreg : std_logic_vector(3 downto 0);
28+
signal btn_deb_comb : std_logic;
29+
signal btn_deb_reg : std_logic;
30+
signal btn_deb_en_reg : std_logic;
31+
32+
begin
33+
34+
-- -------------------------------------------------------------------------
35+
-- SHIFT REGISTER OF BUTTON RAW SIGNAL
36+
-- -------------------------------------------------------------------------
37+
38+
btn_shreg_p : process (CLK, ASYNC_RST)
39+
begin
40+
if (ASYNC_RST = '1') then
41+
btn_raw_shreg <= (others => '0');
42+
elsif (rising_edge(CLK)) then
43+
if (CLK_EN_1K = '1') then
44+
btn_raw_shreg <= btn_raw_shreg(2 downto 0) & BTN_RAW;
45+
end if;
46+
end if;
47+
end process;
48+
49+
-- -------------------------------------------------------------------------
50+
-- DEBOUNCE REGISTER OF BUTTON RAW SIGNAL
51+
-- -------------------------------------------------------------------------
52+
53+
btn_deb_comb <= btn_raw_shreg(0) and btn_raw_shreg(1) and
54+
btn_raw_shreg(2) and btn_raw_shreg(3);
55+
56+
btn_deb_reg_p : process (CLK, ASYNC_RST)
57+
begin
58+
if (ASYNC_RST = '1') then
59+
btn_deb_reg <= '0';
60+
elsif (rising_edge(CLK)) then
61+
btn_deb_reg <= btn_deb_comb;
62+
end if;
63+
end process;
64+
65+
BTN_DEB <= btn_deb_reg;
66+
67+
-- -------------------------------------------------------------------------
68+
-- RISING EDGE DETECTOR OF BUTTON DEBOUNCE SIGNAL
69+
-- -------------------------------------------------------------------------
70+
71+
sseg_an_cnt_p : process (CLK, ASYNC_RST)
72+
begin
73+
if (ASYNC_RST = '1') then
74+
btn_deb_en_reg <= '0';
75+
elsif (rising_edge(CLK)) then
76+
btn_deb_en_reg <= btn_deb_comb and not btn_deb_reg;
77+
end if;
78+
end process;
79+
80+
BTN_DEB_EN <= btn_deb_en_reg;
81+
82+
end RTL;

example/comp/clk_en_gen.vhd

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
--------------------------------------------------------------------------------
2+
-- PROJECT: FPGA MISC
3+
--------------------------------------------------------------------------------
4+
-- NAME: CLK_EN_GEN
5+
-- AUTHORS: Jakub Cabal <[email protected]>
6+
-- LICENSE: The MIT License
7+
-- WEBSITE: https://github.com/jakubcabal/fpga-misc
8+
--------------------------------------------------------------------------------
9+
10+
library IEEE;
11+
use IEEE.STD_LOGIC_1164.ALL;
12+
use IEEE.NUMERIC_STD.ALL;
13+
use IEEE.MATH_REAL.ALL;
14+
15+
entity CLK_EN_GEN is
16+
Generic (
17+
CLK_FREQ : natural := 50e6 -- set system clock frequency in Hz
18+
);
19+
Port (
20+
CLK : in std_logic; -- system clock
21+
ASYNC_RST : in std_logic; -- asynchrounous reset
22+
CLK_EN_1K : out std_logic -- clock enable 1 KHz output
23+
);
24+
end CLK_EN_GEN;
25+
26+
architecture RTL of CLK_EN_GEN is
27+
28+
constant CLK_EN_1K_DIV : integer := CLK_FREQ/1e3;
29+
30+
signal clk_en_1k_cnt : integer range 0 to CLK_EN_1K_DIV-1;
31+
signal clk_en_1k_comb : std_logic;
32+
signal clk_en_1k_reg : std_logic;
33+
34+
begin
35+
36+
-- -------------------------------------------------------------------------
37+
-- COUNTER OF CLOCK ENABLE (~1KHz)
38+
-- -------------------------------------------------------------------------
39+
40+
clk_en_1k_cnt_p : process (CLK, ASYNC_RST)
41+
begin
42+
if (ASYNC_RST = '1') then
43+
clk_en_1k_cnt <= 0;
44+
elsif (rising_edge(CLK)) then
45+
if (clk_en_1k_cnt = CLK_EN_1K_DIV-1) then
46+
clk_en_1k_cnt <= 0;
47+
else
48+
clk_en_1k_cnt <= clk_en_1k_cnt + 1;
49+
end if;
50+
end if;
51+
end process;
52+
53+
-- -------------------------------------------------------------------------
54+
-- GENERATOR OF CLOCK ENABLE (~1KHz)
55+
-- -------------------------------------------------------------------------
56+
57+
clk_en_1k_comb <= '1' when (clk_en_1k_cnt = CLK_EN_1K_DIV-1) else '0';
58+
59+
clk_en_1k_reg_p : process (CLK, ASYNC_RST)
60+
begin
61+
if (ASYNC_RST = '1') then
62+
clk_en_1k_reg <= '0';
63+
elsif (rising_edge(CLK)) then
64+
clk_en_1k_reg <= clk_en_1k_comb;
65+
end if;
66+
end process;
67+
68+
CLK_EN_1K <= clk_en_1k_reg;
69+
70+
end RTL;

example/comp/sseg_driver.vhd

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
--------------------------------------------------------------------------------
2+
-- PROJECT: FPGA MISC
3+
--------------------------------------------------------------------------------
4+
-- NAME: SSEG_DRIVER
5+
-- AUTHORS: Jakub Cabal <[email protected]>
6+
-- LICENSE: The MIT License
7+
-- WEBSITE: https://github.com/jakubcabal/fpga-misc
8+
--------------------------------------------------------------------------------
9+
10+
library IEEE;
11+
use IEEE.STD_LOGIC_1164.ALL;
12+
use IEEE.NUMERIC_STD.ALL;
13+
14+
entity SSEG_DRIVER is
15+
Port (
16+
CLK : in std_logic; -- system clock
17+
CLK_EN_1K : in std_logic; -- clock enable 1 KHz
18+
ASYNC_RST : in std_logic; -- asynchrounous reset
19+
-- USER INTERFACE
20+
DATA0 : in std_logic_vector(3 downto 0); -- BCD or HEX(4b)
21+
DATA1 : in std_logic_vector(3 downto 0); -- BCD or HEX(4b)
22+
DATA2 : in std_logic_vector(3 downto 0); -- BCD or HEX(4b)
23+
DATA3 : in std_logic_vector(3 downto 0); -- BCD or HEX(4b)
24+
DOTS : in std_logic_vector(3 downto 0); -- DP on/off
25+
-- SSEG INTERFACE
26+
SSEG : out std_logic_vector(7 downto 0); -- "dot" & "gfedcba"
27+
SSEG_AN : out std_logic_vector(3 downto 0) -- sseg anodes
28+
);
29+
end SSEG_DRIVER;
30+
31+
architecture RTL of SSEG_DRIVER is
32+
33+
signal sseg_anode_cnt : unsigned(1 downto 0);
34+
signal sseg_anode : std_logic_vector(3 downto 0);
35+
signal sseg_anode_reg : std_logic_vector(3 downto 0);
36+
signal sseg_bin : std_logic_vector(3 downto 0);
37+
signal sseg_code : std_logic_vector(6 downto 0);
38+
signal sseg_dp : std_logic;
39+
signal sseg_REG : std_logic_vector(7 downto 0);
40+
41+
begin
42+
43+
-- -------------------------------------------------------------------------
44+
-- SSEG ANODE MUXING
45+
-- -------------------------------------------------------------------------
46+
47+
sseg_an_cnt_p : process (CLK, ASYNC_RST)
48+
begin
49+
if (ASYNC_RST = '1') then
50+
sseg_anode_cnt <= (others => '0');
51+
elsif (rising_edge(CLK)) then
52+
if (CLK_EN_1K = '1') then
53+
sseg_anode_cnt <= sseg_anode_cnt + 1;
54+
end if;
55+
end if;
56+
end process;
57+
58+
process(sseg_anode_cnt, DATA0, DATA1, DATA2, DATA3, DOTS)
59+
begin
60+
case sseg_anode_cnt is
61+
when "00" =>
62+
sseg_bin <= DATA0;
63+
sseg_dp <= not DOTS(0);
64+
sseg_anode <= "1110";
65+
when "01" =>
66+
sseg_bin <= DATA1;
67+
sseg_dp <= not DOTS(1);
68+
sseg_anode <= "1101";
69+
when "10" =>
70+
sseg_bin <= DATA2;
71+
sseg_dp <= not DOTS(2);
72+
sseg_anode <= "1011";
73+
when "11" =>
74+
sseg_bin <= DATA3;
75+
sseg_dp <= not DOTS(3);
76+
sseg_anode <= "0111";
77+
when others =>
78+
sseg_bin <= DATA0;
79+
sseg_dp <= not DOTS(0);
80+
sseg_anode <= "1110";
81+
end case;
82+
end process;
83+
84+
-- -------------------------------------------------------------------------
85+
-- SSEG ANODE REGISTER
86+
-- -------------------------------------------------------------------------
87+
88+
sseg_anode_reg_p : process (CLK, ASYNC_RST)
89+
begin
90+
if (ASYNC_RST = '1') then
91+
sseg_anode_reg <= (others => '1');
92+
elsif (rising_edge(CLK)) then
93+
sseg_anode_reg <= sseg_anode;
94+
end if;
95+
end process;
96+
97+
SSEG_AN <= sseg_anode_reg;
98+
99+
-- -------------------------------------------------------------------------
100+
-- SSEG DECODER
101+
-- -------------------------------------------------------------------------
102+
103+
with sseg_bin select
104+
sseg_code <= "1000000" when "0000", -- 0
105+
"1111001" when "0001", -- 1
106+
"0100100" when "0010", -- 2
107+
"0110000" when "0011", -- 3
108+
"0011001" when "0100", -- 4
109+
"0010010" when "0101", -- 5
110+
"0000010" when "0110", -- 6
111+
"1111000" when "0111", -- 7
112+
"0000000" when "1000", -- 8
113+
"0010000" when "1001", -- 9
114+
"0001000" when "1010", -- A
115+
"0000011" when "1011", -- B
116+
"1000110" when "1100", -- C
117+
"0100001" when "1101", -- D
118+
"0000110" when "1110", -- E
119+
"0001110" when "1111", -- F
120+
"1111111" when others; -- nic
121+
-- "gfedcba"
122+
123+
-- -------------------------------------------------------------------------
124+
-- SSEG REGISTER
125+
-- -------------------------------------------------------------------------
126+
127+
sseg_reg_p : process (CLK, ASYNC_RST)
128+
begin
129+
if (ASYNC_RST = '1') then
130+
sseg_reg <= (others => '1');
131+
elsif (rising_edge(CLK)) then
132+
sseg_reg <= sseg_dp & sseg_code;
133+
end if;
134+
end process;
135+
136+
SSEG <= sseg_reg;
137+
138+
end RTL;

0 commit comments

Comments
 (0)