version not running!
[calu.git] / cpu / src / writeback_stage_b.vhd
1 library IEEE;
2 use IEEE.std_logic_1164.all;
3 use IEEE.numeric_std.all;
4
5 use work.common_pkg.all;
6 use work.core_pkg.all;
7
8 use work.mem_pkg.all;
9 use work.extension_pkg.all;
10 use work.extension_uart_pkg.all;
11 use work.extension_7seg_pkg.all;
12
13 architecture behav of writeback_stage is
14
15 signal data_ram_read, data_ram_read_ext : word_t;
16 signal data_addr : word_t;
17
18 signal wb_reg, wb_reg_nxt : writeback_rec;
19
20 signal ext_uart,ext_timer,ext_gpmp,ext_7seg :  extmod_rec;
21
22 signal sel_nxt, dmem_we, bus_rx :std_logic;
23
24 signal calc_mem_res : gp_register_t;
25
26 begin
27
28
29         data_ram : r_w_ram
30                 generic map (
31                         DATA_ADDR_WIDTH,
32                         WORD_WIDTH
33                 )
34                 
35                 port map (
36                         clk,
37                         data_addr(DATA_ADDR_WIDTH+1 downto 2),
38                         data_addr(DATA_ADDR_WIDTH+1 downto 2),
39                         dmem_we,
40                         ram_data,
41                         data_ram_read
42                 );
43
44 uart : extension_uart 
45         generic map(
46                 RESET_VALUE
47                 )
48         port map(
49                         clk ,
50                         reset,
51                         ext_uart,
52                         data_ram_read_ext,
53                         bus_rx,
54                         bus_tx
55                 );
56         
57 sseg : extension_7seg
58         generic map(
59                 RESET_VALUE
60                 )
61         port map(
62                 clk,
63                 reset,
64                 ext_7seg,
65                 sseg0,
66                 sseg1,
67                 sseg2,
68                 sseg3
69                 );
70         
71 syn: process(clk, reset)
72
73 begin
74
75         if (reset = RESET_VALUE) then
76                 wb_reg.address <= (others => '0');
77                 wb_reg.dmem_en <= '0';
78                 wb_reg.dmem_write_en <= '0';
79                 wb_reg.hword <= '0';
80                 wb_reg.byte_s <= '0';
81                 bus_rx <= '1';
82         elsif rising_edge(clk) then
83                 wb_reg <= wb_reg_nxt;
84                 bus_rx <= '1';
85         end if;
86         
87 end process; 
88
89 --      type writeback_rec is record
90 --              address : in word_t;            --ureg 
91 --              dmem_en : in std_logic;         --ureg (jump addr in mem or in address)
92 --              dmem_write_en : in std_logic;   --ureg
93 --              hword_hl : in std_logic         --ureg
94 --      end record;
95
96
97
98 shift_input: process(data_ram_read, address, dmem_en, dmem_write_en, hword, wb_reg, result, byte_s, alu_jmp, br_pred, write_en)
99
100 begin
101         wb_reg_nxt.address <= address;
102         wb_reg_nxt.dmem_en <= dmem_en;
103         wb_reg_nxt.dmem_write_en <= dmem_write_en;
104         wb_reg_nxt.hword <= hword;
105         wb_reg_nxt.byte_s <= byte_s;
106
107         calc_mem_res <= result; --(others => '0');
108
109         if (wb_reg.dmem_en = '1' and wb_reg.dmem_write_en = '0') then   -- ram read operation --alu_jmp = '0' and 
110                 calc_mem_res <= data_ram_read;
111                 if (wb_reg.hword = '1') then
112                         calc_mem_res <= (others => '0');
113                         if (wb_reg.address(1) = '1') then
114                                 calc_mem_res(15 downto 0) <= data_ram_read(31 downto 16);
115                         else
116                                 calc_mem_res(15 downto 0) <= data_ram_read(15 downto 0);
117                         end if;
118                 end if;
119                 if (wb_reg.byte_s = '1') then
120                         calc_mem_res <= (others => '0');
121                         case wb_reg.address(1 downto 0) is
122                                 when "00" => calc_mem_res(7 downto 0) <= data_ram_read(7 downto 0);
123                                 when "01" => calc_mem_res(7 downto 0) <= data_ram_read(15 downto 8);
124                                 when "10" => calc_mem_res(7 downto 0) <= data_ram_read(23 downto 16);
125                                 when "11" => calc_mem_res(7 downto 0) <= data_ram_read(31 downto 24);
126                                 when others => null;
127                         end case;
128                 end if; 
129         end if;
130
131         --jump <= (alu_jmp xor br_pred) and (write_en or wb_reg.dmem_en);
132         jump <= (alu_jmp xor br_pred);-- and (write_en or wb_reg.dmem_en);
133
134         if (alu_jmp = '1' and wb_reg.dmem_en = '1' and wb_reg.dmem_write_en = '0' and write_en = '0') then
135                 jump_addr <= data_ram_read;
136         else
137                 jump_addr <= result;    
138         end if;
139
140 --      if alu_jmp = '0' and br_pred = '1' and write_en = '0' then
141 --              jump <= '1';
142 --      end if;
143
144 --      if ((alu_jmp and wb_reg.dmem_en) = '1') then
145 --              jump_addr <= data_ram_read;
146 --      end if;
147
148 end process;
149
150 --                      result : in gp_register_t;      --reg  (alu result or jumpaddr)
151 --                      result_addr : in gp_addr_t;     --reg
152 --                      address : in word_t;            --ureg 
153 --                      alu_jmp : in std_logic;         --reg
154 --                      br_pred : in std_logic;         --reg
155 --                      write_en : in std_logic;        --reg  (register file)
156 --                      dmem_en : in std_logic;         --ureg (jump addr in mem or in result)
157 --                      dmem_write_en : in std_logic;   --ureg
158 --                      hword : in std_logic            --ureg
159
160
161
162 out_logic: process(write_en, result_addr, wb_reg, alu_jmp, wb_reg_nxt, data_ram_read_ext, calc_mem_res)
163
164 begin   
165         reg_we <= (write_en or (wb_reg.dmem_en and not(wb_reg.dmem_write_en))) and not(alu_jmp);
166         reg_addr <= result_addr;
167
168         data_addr <= (others => '0');
169         dmem_we <= '0';
170         
171         if (wb_reg_nxt.address(DATA_ADDR_WIDTH+2) /= '1') then
172                 data_addr(DATA_ADDR_WIDTH+1 downto 0) <= wb_reg_nxt.address(DATA_ADDR_WIDTH+1 downto 0);
173                 dmem_we <= wb_reg_nxt.dmem_write_en;
174         end if;
175         
176         regfile_val <= calc_mem_res;
177
178         if (wb_reg.address(31 downto 4) = EXT_UART_ADDR) then
179                 regfile_val <= data_ram_read_ext;
180         end if;
181 end process;
182
183
184 addr_de_mult: process(wb_reg_nxt, ram_data, wb_reg,sel_nxt)
185
186 begin
187
188   ext_uart.sel <='0';
189   ext_uart.wr_en <= wb_reg_nxt.dmem_write_en;
190   ext_uart.byte_en <= (others => '0');
191   ext_uart.data <= (others => '0');
192   ext_uart.addr <= (others => '0');
193
194   ext_7seg.sel <='0';
195   ext_7seg.wr_en <= wb_reg_nxt.dmem_write_en;
196   ext_7seg.byte_en <= (others => '0');
197   ext_7seg.data <= (others => '0');
198   ext_7seg.addr <= (others => '0');
199   
200   ext_timer.sel <='0';
201   ext_timer.wr_en <= wb_reg_nxt.dmem_write_en;
202   ext_timer.byte_en <= (others => '0');
203   ext_timer.data <= (others => '0');
204   ext_timer.addr <= (others => '0');
205
206   ext_gpmp.sel <='0';
207   ext_gpmp.wr_en <= wb_reg_nxt.dmem_write_en;
208   ext_gpmp.byte_en <= (others => '0');
209   ext_gpmp.data <= (others => '0');
210   ext_gpmp.addr <= (others => '0');
211    -- wenn ich hier statt dem 4rer die konstante nehme dann gibts an fehler wegen nicht lokaler variable -.-
212  case wb_reg_nxt.address(31 downto 4) is
213 --      when EXT_UART_ADDR => 
214 --              ext_uart.sel <='1';
215 --              ext_uart.wr_en <= wb_reg_nxt.dmem_write_en;
216 --              ext_uart.data <= ram_data;
217 --              ext_uart.addr <= wb_reg_nxt.address(31 downto 2);
218 --              case wb_reg_nxt.address(1 downto 0) is
219 --                              when "00" => ext_uart.byte_en <= "0001";
220 --                              when "01" => ext_uart.byte_en <= "0010";
221 --                              when "10" => ext_uart.byte_en <= "0100";
222 --                              --when "11" => ext_uart.byte_en <= "1000";
223 --                              when "11" => ext_uart.byte_en <= "1111";
224 --                              when others => null;
225 --                      end case;
226
227         when EXT_7SEG_ADDR => 
228                 ext_7seg.sel <='1';
229                 ext_7seg.wr_en <= wb_reg_nxt.dmem_write_en;
230                 ext_7seg.data <= ram_data;
231                 ext_7seg.addr <= wb_reg_nxt.address(31 downto 2);
232                 ext_7seg.byte_en(1 downto 0) <= wb_reg_nxt.address(1 downto 0);
233
234                 
235 --              case wb_reg_nxt.address(1 downto 0) is
236 --                      when "00" => ext_7seg.byte_en <= "0001";
237 --                      when "01" => ext_7seg.byte_en <= "0010";
238 --                      when "10" => ext_7seg.byte_en <= "0100";
239 --                      when "11" => ext_7seg.byte_en <= "1000";
240 --                      when others => null;
241 --              end case;
242                         
243         when EXT_TIMER_ADDR => 
244                 ext_timer.sel <='1';
245                 ext_timer.wr_en <= wb_reg_nxt.dmem_write_en;
246                 ext_timer.data <= ram_data;
247                 ext_timer.addr <= wb_reg_nxt.address(wb_reg_nxt.address'high downto BYTEADDR);
248                 case wb_reg.address(1 downto 0) is
249                                 when "00" => ext_timer.byte_en <= "0001";
250                                 when "01" => ext_timer.byte_en <= "0010";
251                                 when "10" => ext_timer.byte_en <= "0100";
252                                 when "11" => ext_timer.byte_en <= "1000";
253                                 when others => null;
254                         end case;
255         when EXT_GPMP_ADDR => 
256                 ext_gpmp.sel <='1';
257                 ext_gpmp.wr_en <= wb_reg_nxt.dmem_write_en;
258                 ext_gpmp.data <= ram_data;
259                 ext_gpmp.addr <= wb_reg_nxt.address(wb_reg_nxt.address'high downto BYTEADDR);
260                 case wb_reg.address(1 downto 0) is
261                                 when "00" => ext_gpmp.byte_en <= "0001";
262                                 when "01" => ext_gpmp.byte_en <= "0010";
263                                 when "10" => ext_gpmp.byte_en <= "0100";
264                                 when "11" => ext_gpmp.byte_en <= "1000";
265                                 when others => null;
266                         end case;
267         -- hier kann man weiter extensions adden :) Konstanten sind im extension pkg definiert 
268         when others => null;
269  end case;
270
271 end process;
272
273 end behav;
274