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

Subversion Repositories lxp32

[/] [lxp32/] [trunk/] [rtl/] [lxp32_dbus.vhd] - Blame information for rev 10

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 ring0_mipt
---------------------------------------------------------------------
2
-- DBUS master
3
--
4
-- Part of the LXP32 CPU
5
--
6
-- Copyright (c) 2016 by Alex I. Kuznetsov
7
--
8
-- Manages data bus (DBUS) access.
9
---------------------------------------------------------------------
10
 
11
library ieee;
12
use ieee.std_logic_1164.all;
13
use ieee.numeric_std.all;
14
 
15
entity lxp32_dbus is
16
        generic(
17
                RMW: boolean
18
        );
19
        port(
20
                clk_i: in std_logic;
21
                rst_i: in std_logic;
22
 
23
                valid_i: in std_logic;
24
 
25
                cmd_dbus_i: in std_logic;
26
                cmd_dbus_store_i: in std_logic;
27
                cmd_dbus_byte_i: in std_logic;
28
                cmd_signed_i: in std_logic;
29
                addr_i: in std_logic_vector(31 downto 0);
30
                wdata_i: in std_logic_vector(31 downto 0);
31
 
32
                rdata_o: out std_logic_vector(31 downto 0);
33
                we_o: out std_logic;
34
                busy_o: out std_logic;
35
 
36
                dbus_cyc_o: out std_logic;
37
                dbus_stb_o: out std_logic;
38
                dbus_we_o: out std_logic;
39
                dbus_sel_o: out std_logic_vector(3 downto 0);
40
                dbus_ack_i: in std_logic;
41
                dbus_adr_o: out std_logic_vector(31 downto 2);
42
                dbus_dat_o: out std_logic_vector(31 downto 0);
43
                dbus_dat_i: in std_logic_vector(31 downto 0)
44
        );
45
end entity;
46
 
47
architecture rtl of lxp32_dbus is
48
 
49
signal strobe: std_logic:='0';
50
signal we_out: std_logic:='0';
51
signal we: std_logic;
52
signal byte_mode: std_logic;
53
signal sel: std_logic_vector(3 downto 0);
54
signal sig: std_logic;
55
signal rmw_mode: std_logic;
56
 
57
signal dbus_rdata: std_logic_vector(31 downto 0);
58
signal selected_byte: std_logic_vector(7 downto 0);
59
 
60
begin
61
 
62
process (clk_i) is
63
begin
64
        if rising_edge(clk_i) then
65
                if rst_i='1' then
66
                        we_out<='0';
67
                        strobe<='0';
68
                        sig<='-';
69
                        byte_mode<='-';
70
                        sel<=(others=>'-');
71
                        we<='-';
72
                        rmw_mode<='-';
73
                        dbus_adr_o<=(others=>'-');
74
                        dbus_dat_o<=(others=>'-');
75
                else
76
                        we_out<='0';
77
                        if strobe='0' then
78
                                if valid_i='1' and cmd_dbus_i='1' then
79
                                        strobe<='1';
80
                                        sig<=cmd_signed_i;
81
 
82
                                        dbus_adr_o<=addr_i(31 downto 2);
83
 
84
                                        if cmd_dbus_byte_i='0' then
85
                                                byte_mode<='0';
86
                                                dbus_dat_o<=wdata_i;
87
                                                sel<="1111";
88
 
89
                                                -- synthesis translate_off
90
                                                assert addr_i(1 downto 0)="00"
91
                                                        report "Misaligned word-granular access on data bus"
92
                                                        severity warning;
93
                                                -- synthesis translate_on
94
                                        else
95
                                                byte_mode<='1';
96
                                                dbus_dat_o<=wdata_i(7 downto 0)&wdata_i(7 downto 0)&
97
                                                        wdata_i(7 downto 0)&wdata_i(7 downto 0);
98
 
99
                                                case addr_i(1 downto 0) is
100
                                                when "00" => sel<="0001";
101
                                                when "01" => sel<="0010";
102
                                                when "10" => sel<="0100";
103
                                                when "11" => sel<="1000";
104
                                                when others =>
105
                                                end case;
106
                                        end if;
107
 
108
                                        if not RMW then
109
                                                we<=cmd_dbus_store_i;
110
                                                rmw_mode<='0';
111
                                        else
112
                                                we<=cmd_dbus_store_i and not cmd_dbus_byte_i;
113
                                                rmw_mode<=cmd_dbus_store_i and cmd_dbus_byte_i;
114
                                        end if;
115
                                end if;
116
                        else
117
                                if dbus_ack_i='1' then
118
                                        if rmw_mode='1' and we='0' and RMW then
119
                                                we<='1';
120
                                                for i in sel'range loop
121
                                                        if sel(i)='0' then
122
                                                                dbus_dat_o(i*8+7 downto i*8)<=
123
                                                                        dbus_dat_i(i*8+7 downto i*8);
124
                                                        end if;
125
                                                end loop;
126
                                        else
127
                                                strobe<='0';
128
                                                if we='0' then
129
                                                        we_out<='1';
130
                                                end if;
131
                                        end if;
132
                                end if;
133
                        end if;
134
                end if;
135
        end if;
136
end process;
137
 
138
dbus_cyc_o<=strobe;
139
dbus_stb_o<=strobe;
140
dbus_we_o<=we;
141
 
142
sel_no_rmw_gen: if not RMW generate
143
        dbus_sel_o<=sel;
144
end generate;
145
 
146
sel_rmw_gen: if RMW generate
147
        dbus_sel_o<=(others=>'1');
148
end generate;
149
 
150
process (clk_i) is
151
begin
152
        if rising_edge(clk_i) then
153
                dbus_rdata<=dbus_dat_i;
154
        end if;
155
end process;
156
 
157
selected_byte_gen: for i in selected_byte'range generate
158
        selected_byte(i)<=(dbus_rdata(i) and sel(0)) or
159
                (dbus_rdata(i+8) and sel(1)) or
160
                (dbus_rdata(i+16) and sel(2)) or
161
                (dbus_rdata(i+24) and sel(3));
162
end generate;
163
 
164
rdata_o<=dbus_rdata when byte_mode='0' else
165
        X"000000"&selected_byte when selected_byte(selected_byte'high)='0' or sig='0' else
166
        X"FFFFFF"&selected_byte;
167
 
168
we_o<=we_out;
169
busy_o<=strobe or we_out;
170
 
171
end architecture;

powered by: WebSVN 2.1.0

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