]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/lx-rocon_tumbl/lx_rocon_gprf_abd.vhd
94cf3da29d2651efdf490683e86ec5b08e22ea85
[fpga/lx-cpu1/lx-rocon.git] / hw / lx-rocon_tumbl / lx_rocon_gprf_abd.vhd
1 library ieee;
2
3 use ieee.std_logic_1164.all;
4 use ieee.std_logic_arith.all;
5 use ieee.std_logic_unsigned.all;
6 use ieee.numeric_std.all;
7 use work.mbl_pkg.all;
8 use work.lx_rocon_pkg.all;
9
10 -- 32x32b General Puprose Registers for Tumbl Core
11 -- Uses 3 BRAMs
12
13 entity lx_rocon_gprf_abd is
14         port
15         (
16                 clk_i        :  in std_logic;
17                 rst_i        :  in std_logic;
18                 clken_i      :  in std_logic;
19                 --
20                 ID2GPRF_i    :  in ID2GPRF_Type;
21                 MEM_WRB_i    :  in WRB_Type;
22                 GPRF2EX_o    :  out GPRF2EX_Type
23         );
24 end entity lx_rocon_gprf_abd;
25
26 architecture rtl of lx_rocon_gprf_abd is
27
28         signal  rdix_rA_s    : std_logic_vector(4 downto 0);
29         signal  rdix_rB_s    : std_logic_vector(4 downto 0);
30         signal  rdix_rD_s    : std_logic_vector(4 downto 0);
31
32         signal  wre_rD_s     : std_logic;
33         signal  ena_rA_s     : std_logic;
34         signal  ena_rB_s     : std_logic;
35         signal  ena_rD_s     : std_logic;
36
37         signal  clken_s      : std_logic;
38
39         signal  wthru_rA_r   : std_logic;
40         signal  rA_DOA_s     : std_logic_vector(31 downto 0);
41         signal  rA_DOB_s     : std_logic_vector(31 downto 0);
42         signal  wthru_rB_r   : std_logic;
43         signal  rB_DOA_s     : std_logic_vector(31 downto 0);
44         signal  rB_DOB_s     : std_logic_vector(31 downto 0);
45         signal  wthru_rD_r   : std_logic;
46         signal  rD_DOA_s     : std_logic_vector(31 downto 0);
47         signal  rD_DOB_s     : std_logic_vector(31 downto 0);
48
49 begin
50
51         -- writeback if WRB_EX or WRB_MEM, but not when r0 involved
52         wre_rD_s <= '1' when ((MEM_WRB_i.wrb_Action /= NO_WRB) and
53                                                         (MEM_WRB_i.wrix_rD /= "00000")) else '0';
54
55         -- ports A should remain unchanged when clken_i is low, while also
56         -- reading from the same address as will be written to should be disabled
57         -- (setup for writeThru of data_rD)
58         ena_rA_s <= '1' when rst_i = '1' else clken_i when ((ID2GPRF_i.rdix_rA /= MEM_WRB_i.wrix_rD)) else '0';
59         ena_rB_s <= '1' when rst_i = '1' else clken_i when ((ID2GPRF_i.rdix_rB /= MEM_WRB_i.wrix_rD)) else '0';
60         ena_rD_s <= '1' when rst_i = '1' else clken_i when ((ID2GPRF_i.rdix_rD /= MEM_WRB_i.wrix_rD)) else '0';
61
62         -- make sure reset does it's job (writes 0 to R0 and resets the ports)
63         clken_s <= rst_i or clken_i;
64         rdix_rA_s <= (others => '0') when rst_i = '1' else ID2GPRF_i.rdix_rA;
65         rdix_rB_s <= (others => '0') when rst_i = '1' else ID2GPRF_i.rdix_rB;
66         rdix_rD_s <= (others => '0') when rst_i = '1' else ID2GPRF_i.rdix_rD;
67
68         GPRF2EX_o.data_rA <= rA_DOA_s when (wthru_rA_r = '0') else rA_DOB_s;
69         GPRF2EX_o.data_rB <= rB_DOA_s when (wthru_rB_r = '0') else rB_DOB_s;
70         GPRF2EX_o.data_rD <= rD_DOA_s when (wthru_rD_r = '0') else rD_DOB_s;    -- also for rD ???
71
72         I_rA: xilinx_dualport_bram
73         generic map
74         (
75                 byte_width    => 32,
76                 we_width      => 1,
77                 address_width => 5,
78                 port_a_type   => WRITE_FIRST,
79                 port_b_type   => WRITE_FIRST
80         )
81         port map
82         (
83                 clka   => clk_i,
84                 rsta   => rst_i,
85                 ena    => ena_rA_s,
86                 wea(0) => rst_i,
87                 addra  => rdix_rA_s,
88                 dina   => C_32_ZEROS,
89                 douta  => rA_DOA_s,
90                 -- Write-back
91                 clkb   => clk_i,
92                 rstb   => rst_i,
93                 enb    => clken_s,
94                 web(0) => wre_rD_s,
95                 addrb  => MEM_WRB_i.wrix_rD,
96                 dinb   => MEM_WRB_i.data_rD,
97                 doutb  => rA_DOB_s
98         );
99
100         I_rB: xilinx_dualport_bram
101         generic map
102         (
103                 byte_width    => 32,
104                 we_width      => 1,
105                 address_width => 5,
106                 port_a_type   => WRITE_FIRST,
107                 port_b_type   => WRITE_FIRST
108         )
109         port map
110         (
111                 clka   => clk_i,
112                 rsta   => rst_i,
113                 ena    => ena_rB_s,
114                 wea(0) => rst_i,
115                 addra  => rdix_rB_s,
116                 dina   => C_32_ZEROS,
117                 douta  => rB_DOA_s,
118                 -- Write-back
119                 clkb   => clk_i,
120                 rstb   => rst_i,
121                 enb    => clken_s,
122                 web(0) => wre_rD_s,
123                 addrb  => MEM_WRB_i.wrix_rD,
124                 dinb   => MEM_WRB_i.data_rD,
125                 doutb  => rB_DOB_s
126         );
127
128         I_rD: xilinx_dualport_bram
129         generic map
130         (
131                 byte_width    => 32,
132                 we_width      => 1,
133                 address_width => 5,
134                 port_a_type   => WRITE_FIRST,
135                 port_b_type   => WRITE_FIRST
136         )
137         port map
138         (
139                 clka   => clk_i,
140                 rsta   => rst_i,
141                 ena    => ena_rD_s,
142                 wea(0) => rst_i,
143                 addra  => rdix_rD_s,
144                 dina   => C_32_ZEROS,
145                 douta  => rD_DOA_s,
146                 -- Write-back
147                 clkb   => clk_i,
148                 rstb   => rst_i,
149                 enb    => clken_s,
150                 web(0) => wre_rD_s,
151                 addrb  => MEM_WRB_i.wrix_rD,
152                 dinb   => MEM_WRB_i.data_rD,
153                 doutb  => rD_DOB_s
154         );
155
156 p_regd:
157         process
158         begin
159                 wait until clk_i'event and clk_i = '1';
160                 if (clken_i = '1') then
161                         wthru_rA_r <= not ena_rA_s;
162                         wthru_rB_r <= not ena_rB_s;
163                         wthru_rD_r <= not ena_rD_s;
164                 end if;
165         end process;
166
167 end architecture rtl;