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

Subversion Repositories lxp32

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

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

Line No. Rev Author Line
1 2 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 selected_byte: std_logic_vector(7 downto 0);
58
 
59
begin
60
 
61
process (clk_i) is
62
begin
63
        if rising_edge(clk_i) then
64
                if rst_i='1' then
65
                        we_out<='0';
66
                        strobe<='0';
67
                else
68
                        we_out<='0';
69
                        if strobe='0' then
70
                                if valid_i='1' and cmd_dbus_i='1' then
71
                                        strobe<='1';
72
                                        sig<=cmd_signed_i;
73
 
74
                                        dbus_adr_o<=addr_i(31 downto 2);
75
                                        dbus_dat_o<=wdata_i;
76
 
77
                                        if cmd_dbus_byte_i='0' then
78
                                                byte_mode<='0';
79
                                                sel<="1111";
80
 
81
                                                -- synthesis translate_off
82
                                                assert addr_i(1 downto 0)="00"
83
                                                        report "Misaligned word-granular access on data bus"
84
                                                        severity warning;
85
                                                -- synthesis translate_on
86
                                        else
87
                                                byte_mode<='1';
88
                                                case addr_i(1 downto 0) is
89
                                                when "00" => sel<="0001"; dbus_dat_o(7 downto 0)<=wdata_i(7 downto 0);
90
                                                when "01" => sel<="0010"; dbus_dat_o(15 downto 8)<=wdata_i(7 downto 0);
91
                                                when "10" => sel<="0100"; dbus_dat_o(23 downto 16)<=wdata_i(7 downto 0);
92
                                                when "11" => sel<="1000"; dbus_dat_o(31 downto 24)<=wdata_i(7 downto 0);
93
                                                when others =>
94
                                                end case;
95
                                        end if;
96
 
97
                                        if not RMW then
98
                                                we<=cmd_dbus_store_i;
99
                                                rmw_mode<='0';
100
                                        else
101
                                                we<=cmd_dbus_store_i and not cmd_dbus_byte_i;
102
                                                rmw_mode<=cmd_dbus_store_i and cmd_dbus_byte_i;
103
                                        end if;
104
                                end if;
105
                        else
106
                                if dbus_ack_i='1' then
107
                                        if rmw_mode='1' and we='0' and RMW then
108
                                                we<='1';
109
                                                for i in sel'range loop
110
                                                        if sel(i)='0' then
111
                                                                dbus_dat_o(i*8+7 downto i*8)<=
112
                                                                        dbus_dat_i(i*8+7 downto i*8);
113
                                                        end if;
114
                                                end loop;
115
                                        else
116
                                                strobe<='0';
117
                                                if we='0' then
118
                                                        we_out<='1';
119
                                                end if;
120
                                        end if;
121
                                end if;
122
                        end if;
123
                end if;
124
        end if;
125
end process;
126
 
127
dbus_cyc_o<=strobe;
128
dbus_stb_o<=strobe;
129
dbus_we_o<=we;
130
 
131
sel_no_rmw_gen: if not RMW generate
132
        dbus_sel_o<=sel;
133
end generate;
134
 
135
sel_rmw_gen: if RMW generate
136
        dbus_sel_o<=(others=>'1');
137
end generate;
138
 
139
selected_byte_gen: for i in selected_byte'range generate
140
        selected_byte(i)<=(dbus_dat_i(i) and sel(0)) or
141
                (dbus_dat_i(i+8) and sel(1)) or
142
                (dbus_dat_i(i+16) and sel(2)) or
143
                (dbus_dat_i(i+24) and sel(3));
144
end generate;
145
 
146
process (clk_i) is
147
begin
148
        if rising_edge(clk_i) then
149
                if byte_mode='0' then
150
                        rdata_o<=dbus_dat_i;
151
                else
152
                        rdata_o(7 downto 0)<=selected_byte;
153
                        for i in rdata_o'high downto 8 loop
154
                                rdata_o(i)<=selected_byte(selected_byte'high) and sig;
155
                        end loop;
156
                end if;
157
        end if;
158
end process;
159
 
160
we_o<=we_out;
161
busy_o<=strobe or we_out;
162
 
163
end architecture;

powered by: WebSVN 2.1.0

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