7seg small changes
[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
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         regfile_val <= 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                 regfile_val <= data_ram_read;
111                 if (wb_reg.hword = '1') then
112                         regfile_val <= (others => '0');
113                         if (wb_reg.address(1) = '1') then
114                                 regfile_val(15 downto 0) <= data_ram_read(31 downto 16);
115                         else
116                                 regfile_val(15 downto 0) <= data_ram_read(15 downto 0);
117                         end if;
118                 end if;
119                 if (wb_reg.byte_s = '1') then
120                         regfile_val <= (others => '0');
121                         case wb_reg.address(1 downto 0) is
122                                 when "00" => regfile_val(7 downto 0) <= data_ram_read(7 downto 0);
123                                 when "01" => regfile_val(7 downto 0) <= data_ram_read(15 downto 8);
124                                 when "10" => regfile_val(7 downto 0) <= data_ram_read(23 downto 16);
125                                 when "11" => regfile_val(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)
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 end process;
176
177
178 addr_de_mult: process(wb_reg_nxt.address, ram_data, wb_reg,sel_nxt,wb_reg_nxt.dmem_write_en)
179
180 begin
181   ext_uart.sel <='0';
182   ext_uart.wr_en <= wb_reg_nxt.dmem_write_en;
183   ext_uart.byte_en <= (others => '0');
184   ext_uart.data <= (others => '0');
185   ext_uart.addr <= (others => '0');
186
187   ext_7seg.sel <='0';
188   ext_7seg.wr_en <= wb_reg_nxt.dmem_write_en;
189   ext_7seg.byte_en <= (others => '0');
190   ext_7seg.data <= (others => '0');
191   ext_7seg.addr <= (others => '0');
192   
193   ext_timer.sel <='0';
194   ext_timer.wr_en <= wb_reg_nxt.dmem_write_en;
195   ext_timer.byte_en <= (others => '0');
196   ext_timer.data <= (others => '0');
197   ext_timer.addr <= (others => '0');
198
199   ext_gpmp.sel <='0';
200   ext_gpmp.wr_en <= wb_reg_nxt.dmem_write_en;
201   ext_gpmp.byte_en <= (others => '0');
202   ext_gpmp.data <= (others => '0');
203   ext_gpmp.addr <= (others => '0');
204    -- wenn ich hier statt dem 4rer die konstante nehme dann gibts an fehler wegen nicht lokaler variable -.-
205  case wb_reg_nxt.address(31 downto 4) is
206         when EXT_UART_ADDR => 
207                 ext_uart.sel <='1';
208                 ext_uart.wr_en <= wb_reg_nxt.dmem_write_en;
209                 ext_uart.data <= ram_data;
210                 ext_uart.addr <= wb_reg_nxt.address(31 downto 2);
211                 case wb_reg_nxt.address(1 downto 0) is
212                                 when "00" => ext_uart.byte_en <= "0001";
213                                 when "01" => ext_uart.byte_en <= "0010";
214                                 when "10" => ext_uart.byte_en <= "0100";
215                                 --when "11" => ext_uart.byte_en <= "1000";
216                                 when "11" => ext_uart.byte_en <= "1111";
217                                 when others => null;
218                         end case;
219
220         when EXT_7SEG_ADDR => 
221                 ext_7seg.sel <='1';
222                 ext_7seg.wr_en <= wb_reg_nxt.dmem_write_en;
223                 ext_7seg.data <= ram_data;
224                 ext_7seg.addr <= wb_reg_nxt.address(31 downto 2);
225                 ext_7seg.byte_en(1 downto 0) <= wb_reg_nxt.address(1 downto 0);
226
227                 
228 --              case wb_reg_nxt.address(1 downto 0) is
229 --                      when "00" => ext_7seg.byte_en <= "0001";
230 --                      when "01" => ext_7seg.byte_en <= "0010";
231 --                      when "10" => ext_7seg.byte_en <= "0100";
232 --                      when "11" => ext_7seg.byte_en <= "1000";
233 --                      when others => null;
234 --              end case;
235                         
236         when EXT_TIMER_ADDR => 
237                 ext_timer.sel <='1';
238                 ext_timer.wr_en <= wb_reg_nxt.dmem_write_en;
239                 ext_timer.data <= ram_data;
240                 ext_timer.addr <= wb_reg_nxt.address(wb_reg_nxt.address'high downto BYTEADDR);
241                 case wb_reg.address(1 downto 0) is
242                                 when "00" => ext_timer.byte_en <= "0001";
243                                 when "01" => ext_timer.byte_en <= "0010";
244                                 when "10" => ext_timer.byte_en <= "0100";
245                                 when "11" => ext_timer.byte_en <= "1000";
246                                 when others => null;
247                         end case;
248         when EXT_GPMP_ADDR => 
249                 ext_gpmp.sel <='1';
250                 ext_gpmp.wr_en <= wb_reg_nxt.dmem_write_en;
251                 ext_gpmp.data <= ram_data;
252                 ext_gpmp.addr <= wb_reg_nxt.address(wb_reg_nxt.address'high downto BYTEADDR);
253                 case wb_reg.address(1 downto 0) is
254                                 when "00" => ext_gpmp.byte_en <= "0001";
255                                 when "01" => ext_gpmp.byte_en <= "0010";
256                                 when "10" => ext_gpmp.byte_en <= "0100";
257                                 when "11" => ext_gpmp.byte_en <= "1000";
258                                 when others => null;
259                         end case;
260         -- hier kann man weiter extensions adden :) Konstanten sind im extension pkg definiert 
261         when others => null;
262  end case;
263
264 end process;
265
266 end behav;
267