erster versuch das ganze mal zu flashen -> es blinkt!!111
[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
12 architecture behav of writeback_stage is
13
14 signal data_ram_read, data_ram_read_ext : word_t;
15
16 signal wb_reg, wb_reg_nxt : writeback_rec;
17
18 signal ext_uart,ext_timer,ext_gpmp :  extmod_rec;
19
20 signal sel_nxt :std_logic;
21
22
23
24 begin
25
26
27         data_ram : r_w_ram
28                 generic map (
29                         DATA_ADDR_WIDTH,
30                         WORD_WIDTH
31                 )
32                 
33                 port map (
34                         clk,
35                         wb_reg_nxt.address(DATA_ADDR_WIDTH+1 downto 2),
36                         wb_reg_nxt.address(DATA_ADDR_WIDTH+1 downto 2),
37                         wb_reg_nxt.dmem_write_en,
38                         ram_data,
39                         data_ram_read
40                 );
41
42 uart : extension_uart 
43         generic map(
44                 RESET_VALUE
45                 )
46         port map(
47                         clk ,
48                         reset,
49                         ext_uart,
50                         data_ram_read_ext,
51                         bus_tx
52                 );
53
54         
55 syn: process(clk, reset)
56
57 begin
58
59         if (reset = RESET_VALUE) then
60                 wb_reg.address <= (others => '0');
61                 wb_reg.dmem_en <= '0';
62                 wb_reg.dmem_write_en <= '0';
63                 wb_reg.hword <= '0';
64                 wb_reg.byte_s <= '0';
65         elsif rising_edge(clk) then
66                 wb_reg <= wb_reg_nxt;
67         end if;
68         
69 end process; 
70
71 --      type writeback_rec is record
72 --              address : in word_t;            --ureg 
73 --              dmem_en : in std_logic;         --ureg (jump addr in mem or in address)
74 --              dmem_write_en : in std_logic;   --ureg
75 --              hword_hl : in std_logic         --ureg
76 --      end record;
77
78
79
80 shift_input: process(data_ram_read, address, dmem_en, dmem_write_en, hword, wb_reg, result, byte_s, alu_jmp, br_pred, write_en)
81
82 begin
83         wb_reg_nxt.address <= address;
84         wb_reg_nxt.dmem_en <= dmem_en;
85         wb_reg_nxt.dmem_write_en <= dmem_write_en;
86         wb_reg_nxt.hword <= hword;
87         wb_reg_nxt.byte_s <= byte_s;
88
89         regfile_val <= result; --(others => '0');
90
91         if (wb_reg.dmem_en = '1' and wb_reg.dmem_write_en = '0') then   -- ram read operation --alu_jmp = '0' and 
92                 regfile_val <= data_ram_read;
93                 if (wb_reg.hword = '1') then
94                         regfile_val <= (others => '0');
95                         if (wb_reg.address(1) = '1') then
96                                 regfile_val(15 downto 0) <= data_ram_read(31 downto 16);
97                         else
98                                 regfile_val(15 downto 0) <= data_ram_read(15 downto 0);
99                         end if;
100                 end if;
101                 if (wb_reg.byte_s = '1') then
102                         regfile_val <= (others => '0');
103                         case wb_reg.address(1 downto 0) is
104                                 when "00" => regfile_val(7 downto 0) <= data_ram_read(7 downto 0);
105                                 when "01" => regfile_val(7 downto 0) <= data_ram_read(15 downto 8);
106                                 when "10" => regfile_val(7 downto 0) <= data_ram_read(23 downto 16);
107                                 when "11" => regfile_val(7 downto 0) <= data_ram_read(31 downto 24);
108                                 when others => null;
109                         end case;
110                 end if; 
111         end if;
112
113         --jump <= (alu_jmp xor br_pred) and (write_en or wb_reg.dmem_en);
114         jump <= (alu_jmp xor br_pred);-- and (write_en or wb_reg.dmem_en);
115
116         if (alu_jmp = '1' and wb_reg.dmem_en = '1' and wb_reg.dmem_write_en = '0' and write_en = '0') then
117                 jump_addr <= data_ram_read;
118         else
119                 jump_addr <= result;    
120         end if;
121
122 --      if alu_jmp = '0' and br_pred = '1' and write_en = '0' then
123 --              jump <= '1';
124 --      end if;
125
126 --      if ((alu_jmp and wb_reg.dmem_en) = '1') then
127 --              jump_addr <= data_ram_read;
128 --      end if;
129
130 end process;
131
132 --                      result : in gp_register_t;      --reg  (alu result or jumpaddr)
133 --                      result_addr : in gp_addr_t;     --reg
134 --                      address : in word_t;            --ureg 
135 --                      alu_jmp : in std_logic;         --reg
136 --                      br_pred : in std_logic;         --reg
137 --                      write_en : in std_logic;        --reg  (register file)
138 --                      dmem_en : in std_logic;         --ureg (jump addr in mem or in result)
139 --                      dmem_write_en : in std_logic;   --ureg
140 --                      hword : in std_logic            --ureg
141
142
143
144 out_logic: process(write_en, result_addr, wb_reg, alu_jmp)
145
146 begin   
147         reg_we <= (write_en or (wb_reg.dmem_en and not(wb_reg.dmem_write_en))) and not(alu_jmp);
148         reg_addr <= result_addr;
149 end process;
150
151
152 addr_de_mult: process(wb_reg_nxt.address, ram_data, wb_reg,sel_nxt,wb_reg_nxt.dmem_write_en)
153
154 begin
155                 ext_uart.sel <='0';
156   ext_uart.wr_en <= wb_reg_nxt.dmem_write_en;
157   ext_uart.byte_en <= (others => '0');
158   ext_uart.data <= (others => '0');
159   ext_uart.addr <= (others => '0');
160
161   ext_timer.sel <='0';
162   ext_timer.wr_en <= wb_reg_nxt.dmem_write_en;
163   ext_timer.byte_en <= (others => '0');
164   ext_timer.data <= (others => '0');
165   ext_timer.addr <= (others => '0');
166
167   ext_gpmp.sel <='0';
168   ext_gpmp.wr_en <= wb_reg_nxt.dmem_write_en;
169   ext_gpmp.byte_en <= (others => '0');
170   ext_gpmp.data <= (others => '0');
171   ext_gpmp.addr <= (others => '0');
172                                                  -- wenn ich hier statt dem 4rer die konstante nehme dann gibts an fehler wegen nicht lokaler variable -.-
173  case wb_reg_nxt.address(wb_reg_nxt.address'high downto 4) is
174         when EXT_UART_ADDR => 
175                 ext_uart.sel <='1';
176                 ext_timer.wr_en <= wb_reg_nxt.dmem_write_en;
177                 ext_uart.data <= ram_data;
178                 ext_uart.addr <= wb_reg_nxt.address(wb_reg_nxt.address'high downto BYTEADDR);
179                 case wb_reg.address(1 downto 0) is
180                                 when "00" => ext_uart.byte_en <= "0001";
181                                 when "01" => ext_uart.byte_en <= "0010";
182                                 when "10" => ext_uart.byte_en <= "0100";
183                                 --when "11" => ext_uart.byte_en <= "1000";
184                                 when "11" => ext_uart.byte_en <= "1111";
185                                 when others => null;
186                         end case;
187         when EXT_TIMER_ADDR => 
188                 ext_timer.sel <='1';
189                 ext_timer.wr_en <= wb_reg_nxt.dmem_write_en;
190                 ext_timer.data <= ram_data;
191                 ext_timer.addr <= wb_reg_nxt.address(wb_reg_nxt.address'high downto BYTEADDR);
192                 case wb_reg.address(1 downto 0) is
193                                 when "00" => ext_timer.byte_en <= "0001";
194                                 when "01" => ext_timer.byte_en <= "0010";
195                                 when "10" => ext_timer.byte_en <= "0100";
196                                 when "11" => ext_timer.byte_en <= "1000";
197                                 when others => null;
198                         end case;
199         when EXT_GPMP_ADDR => 
200                 ext_gpmp.sel <='1';
201                 ext_gpmp.wr_en <= wb_reg_nxt.dmem_write_en;
202                 ext_gpmp.data <= ram_data;
203                 ext_gpmp.addr <= wb_reg_nxt.address(wb_reg_nxt.address'high downto BYTEADDR);
204                 case wb_reg.address(1 downto 0) is
205                                 when "00" => ext_gpmp.byte_en <= "0001";
206                                 when "01" => ext_gpmp.byte_en <= "0010";
207                                 when "10" => ext_gpmp.byte_en <= "0100";
208                                 when "11" => ext_gpmp.byte_en <= "1000";
209                                 when others => null;
210                         end case;
211         -- hier kann man weiter extensions adden :) Konstanten sind im extension pkg definiert 
212         when others => null;
213  end case;
214
215 end process;
216
217 end behav;
218