-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathperipherals.vhd
205 lines (183 loc) · 6.15 KB
/
peripherals.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
-- File: peripherals.vhd
-- Author: Richard James Howe
-- Repository: https://github.com./howerj/bit-serial
-- Email: [email protected]
-- License: MIT
-- Description: Memory and Memory mapped peripherals
library ieee, work, std;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.util.all;
use work.uart_pkg.all;
entity peripherals is
generic (
g: common_generics;
file_name: string;
baud: positive;
W: positive;
N: positive;
uart_fifo_depth: natural;
uart_use_cfg: boolean);
port (
clk: in std_ulogic;
rst: in std_ulogic;
rx: in std_ulogic;
tx: out std_ulogic;
ld: out std_ulogic_vector(7 downto 0);
sw: in std_ulogic_vector(7 downto 0);
i, a: in std_ulogic;
o: out std_ulogic;
oe, ie, ae: in std_ulogic);
end;
architecture rtl of peripherals is
constant data_length: positive := N;
constant addr_length: positive := W;
type registers_t is record
r_a: std_ulogic_vector(N - 1 downto 0);
r_i: std_ulogic_vector(N - 1 downto 0);
r_o: std_ulogic_vector(N - 1 downto 0);
r_ld: std_ulogic_vector(ld'range);
r_ie: std_ulogic;
end record;
constant registers_default: registers_t := (
r_a => (others => '0'),
r_i => (others => '0'),
r_o => (others => '0'),
r_ld => (others => '0'),
r_ie => '0'
);
signal c, f: registers_t := registers_default;
signal io, write: boolean := false;
signal dwe, dre: std_ulogic := '0';
signal dout: std_ulogic_vector(N - 1 downto 0) := (others => '0');
signal tx_fifo_full: std_ulogic;
signal tx_fifo_empty: std_ulogic;
signal tx_fifo_we: std_ulogic;
signal tx_fifo_data: std_ulogic_vector(7 downto 0);
signal rx_fifo_full: std_ulogic;
signal rx_fifo_empty: std_ulogic;
signal rx_fifo_re: std_ulogic;
signal rx_fifo_data: std_ulogic_vector(7 downto 0);
signal reg: std_ulogic_vector(15 downto 0);
signal clock_reg_tx_we: std_ulogic;
signal clock_reg_rx_we: std_ulogic;
signal control_reg_we: std_ulogic;
signal io_addr: std_ulogic_vector(2 downto 0);
begin
io <= c.r_a(c.r_a'high - 1) = '1' and ae = '0' after g.delay;
io_addr <= c.r_a(io_addr'range) after g.delay;
write <= true when (c.r_ie and (c.r_ie xor f.r_ie)) = '1' else false after g.delay;
ld <= c.r_ld after g.delay;
o <= c.r_o(0) after g.delay;
tx_fifo_data <= c.r_i(tx_fifo_data'range) after g.delay;
reg <= c.r_i(reg'range) after g.delay;
uart: entity work.uart_top
generic map (
clock_frequency => g.clock_frequency,
delay => g.delay,
asynchronous_reset => g.asynchronous_reset,
baud => baud,
fifo_depth => uart_fifo_depth,
use_cfg => uart_use_cfg)
port map(
clk => clk, rst => rst,
tx => tx,
tx_fifo_full => tx_fifo_full,
tx_fifo_empty => tx_fifo_empty,
tx_fifo_we => tx_fifo_we,
tx_fifo_data => tx_fifo_data,
rx => rx,
rx_fifo_full => rx_fifo_full,
rx_fifo_empty => rx_fifo_empty,
rx_fifo_re => rx_fifo_re,
rx_fifo_data => rx_fifo_data,
reg => reg,
clock_reg_tx_we => clock_reg_tx_we,
clock_reg_rx_we => clock_reg_rx_we,
control_reg_we => control_reg_we);
bram: entity work.single_port_block_ram
generic map(
g => g,
file_name => file_name,
file_type => FILE_HEX,
addr_length => addr_length,
data_length => data_length)
port map (
clk => clk,
dwe => dwe,
addr => f.r_a(addr_length - 1 downto 0),
dre => dre,
din => f.r_i,
dout => dout);
process (clk, rst)
begin
if rst = '1' and g.asynchronous_reset then
c <= registers_default after g.delay;
elsif rising_edge(clk) then
if rst = '1' and not g.asynchronous_reset then
c <= registers_default after g.delay;
else
c <= f after g.delay;
end if;
end if;
end process;
process (c, i, a, oe, ie, ae, dout, io, write, sw, rx, io_addr,
rx_fifo_data, rx_fifo_empty, rx_fifo_full, tx_fifo_empty, tx_fifo_full)
begin
f <= c after g.delay;
f.r_o <= dout after g.delay;
f.r_ie <= ie after g.delay;
dre <= '1' after g.delay;
dwe <= '0' after g.delay;
tx_fifo_we <= '0' after g.delay;
rx_fifo_re <= '0' after g.delay;
clock_reg_tx_we <= '0' after g.delay;
clock_reg_rx_we <= '0' after g.delay;
control_reg_we <= '0' after g.delay;
if ae = '1' then f.r_a <= a & c.r_a(c.r_a'high downto 1) after g.delay; end if;
if oe = '1' then f.r_o <= c.r_o(0) & c.r_o(c.r_o'high downto 1) after g.delay; end if;
if ie = '1' then f.r_i <= i & c.r_i(c.r_i'high downto 1) after g.delay; end if;
if oe = '0' and ae = '0' then
if io = false then
dre <= '1' after g.delay;
else
f.r_o <= (others => '0') after g.delay;
case io_addr is
when "000" => f.r_o(sw'range) <= sw after g.delay;
when "001" =>
f.r_o(7 downto 0) <= rx_fifo_data after g.delay;
f.r_o(8) <= rx_fifo_empty after g.delay;
f.r_o(9) <= rx_fifo_full after g.delay;
f.r_o(11) <= tx_fifo_empty after g.delay;
f.r_o(12) <= tx_fifo_full after g.delay;
when "010" =>
when "011" =>
when "100" =>
when "101" =>
when "110" =>
when "111" =>
when others =>
end case;
end if;
end if;
if write and ae = '0' then
if io = false then
dwe <= '1' after g.delay;
else
case io_addr is
when "000" => f.r_ld <= c.r_i(c.r_ld'range) after g.delay;
when "001" => tx_fifo_we <= c.r_i(13) after g.delay;
rx_fifo_re <= c.r_i(10) after g.delay;
when "010" => if uart_use_cfg then clock_reg_tx_we <= '1' after g.delay; end if;
when "011" => if uart_use_cfg then clock_reg_rx_we <= '1' after g.delay; end if;
when "100" => if uart_use_cfg then control_reg_we <= '1' after g.delay; end if;
when "101" =>
when "110" =>
when "111" =>
when others =>
end case;
end if;
end if;
end process;
end architecture;