OpenCores
URL https://opencores.org/ocsvn/bitserial/bitserial/trunk

Subversion Repositories bitserial

[/] [bitserial/] [trunk/] [peripherals.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.