add read_enable signal to data bus and some peripherals
Stefan Schuermans

Stefan Schuermans commited on 2012-02-26 21:20:53
Showing 6 changed files, with 84 additions and 23 deletions.

... ...
@@ -18,9 +18,8 @@ int eth_can_rx(void)
18 18
  */
19 19
 unsigned char eth_rx(void)
20 20
 {
21
-  while (!eth_ptr[0]); /* wait for data */
22
-  unsigned char chr = eth_ptr[4]; /* read data */
23
-  eth_ptr[4] = 0; /* remove data from FIFO */
21
+  while (!eth_ptr[0]);
22
+  unsigned char chr = eth_ptr[4];
24 23
   return chr;
25 24
 }
26 25
 
... ...
@@ -45,8 +45,8 @@ int uart_can_tx(void)
45 45
  */
46 46
 void uart_tx(unsigned short chr)
47 47
 {
48
-  while (!*(uart_ptr + 4)); /* wait for ready */
49
-  *(unsigned short *)(uart_ptr + 8) = chr; /* write data */
48
+  while (!*(uart_ptr + 4));
49
+  *(unsigned short *)(uart_ptr + 8) = chr;
50 50
 }
51 51
 
52 52
 /**
... ...
@@ -64,9 +64,8 @@ int uart_can_rx(void)
64 64
  */
65 65
 unsigned short uart_rx(void)
66 66
 {
67
-  while (!*(uart_ptr + 5)); /* wait for data */
68
-  unsigned short chr = *(unsigned short *)(uart_ptr + 12); /* read data */
69
-  *(unsigned short *)(uart_ptr + 12) = 0; /* remove data from FIFO */
67
+  while (!*(uart_ptr + 5));
68
+  unsigned short chr = *(unsigned short *)(uart_ptr + 12);
70 69
   return chr;
71 70
 }
72 71
 
... ...
@@ -8,6 +8,7 @@ ENTITY e_io_eth IS
8 8
         clk:          IN  std_logic;
9 9
         i_addr:       IN  std_logic_vector( 1 DOWNTO 0);
10 10
         o_rd_data:    OUT std_logic_vector(31 DOWNTO 0);
11
+        i_rd_en:      IN  std_logic_vector( 3 DOWNTO 0);
11 12
         i_wr_data:    IN  std_logic_vector(31 DOWNTO 0);
12 13
         i_wr_en:      IN  std_logic_vector( 3 DOWNTO 0);
13 14
         pin_o_nrst:   OUT std_logic;
... ...
@@ -134,15 +135,7 @@ BEGIN
134 135
         );
135 136
 
136 137
     -- so far only for testing
137
-    p_rx_test_wr: PROCESS (i_addr, i_wr_data, i_wr_en)
138
-    BEGIN
139
-        s_rx_fifo_rd_en <= '0';
140
-        IF i_addr = "01" THEN
141
-            IF i_wr_en(0) = '1' THEN
142
-                s_rx_fifo_rd_en <= '1';
143
-            END IF;
144
-        END IF;
145
-    END PROCESS p_rx_test_wr;
138
+    s_rx_fifo_rd_en <= '1' WHEN i_addr = "01" AND i_rd_en(0) = '1' ELSE '0';
146 139
 
147 140
     -- so far only for testing
148 141
     p_rx_test_rd: PROCESS (rst, clk)
... ...
@@ -8,6 +8,7 @@ ENTITY e_io_uart IS
8 8
         clk:       IN  std_logic;
9 9
         i_addr:    IN  std_logic_vector( 1 DOWNTO 0);
10 10
         o_rd_data: OUT std_logic_vector(31 DOWNTO 0);
11
+        i_rd_en:   IN  std_logic_vector( 3 DOWNTO 0);
11 12
         i_wr_data: IN  std_logic_vector(31 DOWNTO 0);
12 13
         i_wr_en:   IN  std_logic_vector( 3 DOWNTO 0);
13 14
         pin_i_rx:  IN  std_logic;
... ...
@@ -131,7 +132,7 @@ BEGIN
131 132
         END IF;
132 133
     END PROCESS p_cfg_sync;
133 134
 
134
-    s_rx_rd_en <= '1' WHEN i_addr = "11" AND i_wr_en(1 DOWNTO 0) = "11"
135
+    s_rx_rd_en <= '1' WHEN i_addr = "11" AND i_rd_en(1 DOWNTO 0) = "11"
135 136
                   ELSE '0';
136 137
 
137 138
     rx_fifo: e_block_fifo
... ...
@@ -439,14 +440,26 @@ BEGIN
439 440
             o_rd_data <= (OTHERS => '0');
440 441
             CASE i_addr IS
441 442
                 WHEN "00" =>
443
+                    IF i_rd_en(1 DOWNTO 0) = "11" THEN
442 444
                         o_rd_data(15 DOWNTO  0) <= r_cfg_scale;
445
+                    END IF;
446
+                    IF i_rd_en(2) = '1' THEN
443 447
                         o_rd_data(19 DOWNTO 16) <= r_cfg_bits;
448
+                    END IF;
449
+                    IF i_rd_en(3) = '1' THEN
444 450
                         o_rd_data(25 DOWNTO 24) <= r_cfg_stop;
451
+                    END IF;
445 452
                 WHEN "01" =>
453
+                    IF i_rd_en(0) = '1' THEN
446 454
                         o_rd_data(0) <= s_tx_wr_rdy;
455
+                    END IF;
456
+                    IF i_rd_en(1) = '1' THEN
447 457
                         o_rd_data(8) <= s_rx_rd_rdy;
458
+                    END IF;
448 459
                 WHEN "11" =>
460
+                    IF i_rd_en(1 DOWNTO 0) = "11" THEN
449 461
                         o_rd_data(15 DOWNTO 0) <= s_rx_rd_data;
462
+                    END IF;
450 463
                 WHEN OTHERS =>
451 464
                     NULL;
452 465
             END CASE;
... ...
@@ -12,6 +12,7 @@ ENTITY e_mips_core IS
12 12
         i_instr_data:   IN  std_logic_vector(31 DOWNTO 0);
13 13
         o_data_addr:    OUT std_logic_vector(31 DOWNTO 0);
14 14
         i_data_rd_data: IN  std_logic_vector(31 DOWNTO 0);
15
+        o_data_rd_en:   OUT std_logic_vector( 3 DOWNTO 0);
15 16
         o_data_wr_data: OUT std_logic_vector(31 DOWNTO 0);
16 17
         o_data_wr_en:   OUT std_logic_vector( 3 DOWNTO 0)
17 18
     );
... ...
@@ -419,20 +420,62 @@ BEGIN
419 420
     END PROCESS p_next_pc;
420 421
 
421 422
     p_data_addr: PROCESS(r_op, s_val_s, r_imm_16)
422
-        VARIABLE v_ofs: signed(31 DOWNTO 0);
423
-        VARIABLE v_addr: signed(31 DOWNTO 0);
423
+        VARIABLE v_ofs: unsigned(31 DOWNTO 0);
424
+        VARIABLE v_addr: unsigned(31 DOWNTO 0);
424 425
     BEGIN
425 426
         s_data_addr <= (OTHERS => '0');
426 427
         IF r_op = op_l OR r_op = op_s THEN
427
-            v_ofs(15 DOWNTO 0)  := signed(r_imm_16);
428
+            v_ofs(15 DOWNTO 0)  := unsigned(r_imm_16);
428 429
             v_ofs(31 DOWNTO 16) := (OTHERS => r_imm_16(15));
429
-            v_addr              := signed(s_val_s) + v_ofs;
430
+            v_addr              := unsigned(s_val_s) + v_ofs;
430 431
             s_data_addr         <= std_logic_vector(v_addr);
431 432
         END IF;
432 433
     END PROCESS p_data_addr;
433 434
 
434 435
     o_data_addr <= s_data_addr(31 DOWNTO 2) & "00";
435 436
 
437
+    p_data_rd_en: PROCESS(r_data_rd, r_op, r_ldst, s_data_addr)
438
+    BEGIN
439
+        o_data_rd_en <= "0000";
440
+        IF r_data_rd = data_rd_idle AND r_op = op_l THEN
441
+            CASE r_ldst IS
442
+                WHEN ldst_b | ldst_bu =>
443
+                    CASE s_data_addr(1 DOWNTO 0) IS
444
+                        WHEN "00" => o_data_rd_en <= "0001";
445
+                        WHEN "01" => o_data_rd_en <= "0010";
446
+                        WHEN "10" => o_data_rd_en <= "0100";
447
+                        WHEN "11" => o_data_rd_en <= "1000";
448
+                        WHEN OTHERS => NULL;
449
+                    END CASE;
450
+                WHEN ldst_h | ldst_hu =>
451
+                    CASE s_data_addr(1 DOWNTO 1) IS
452
+                        WHEN "0" => o_data_rd_en <= "0011";
453
+                        WHEN "1" => o_data_rd_en <= "1100";
454
+                        WHEN OTHERS => NULL;
455
+                    END CASE;
456
+                WHEN ldst_w =>
457
+                    o_data_rd_en <= "1111";
458
+                WHEN ldst_wl =>
459
+                    CASE s_data_addr(1 DOWNTO 0) IS
460
+                        WHEN "00" => o_data_rd_en <= "0001";
461
+                        WHEN "01" => o_data_rd_en <= "0011";
462
+                        WHEN "10" => o_data_rd_en <= "0111";
463
+                        WHEN "11" => o_data_rd_en <= "1111";
464
+                        WHEN OTHERS => NULL;
465
+                    END CASE;
466
+                WHEN ldst_wr =>
467
+                    CASE s_data_addr(1 DOWNTO 0) IS
468
+                        WHEN "00" => o_data_rd_en <= "1111";
469
+                        WHEN "01" => o_data_rd_en <= "1110";
470
+                        WHEN "10" => o_data_rd_en <= "1100";
471
+                        WHEN "11" => o_data_rd_en <= "1000";
472
+                        WHEN OTHERS => NULL;
473
+                    END CASE;
474
+                WHEN OTHERS => NULL;
475
+            END CASE;
476
+        END IF;
477
+    END PROCESS p_data_rd_en;
478
+
436 479
     p_data_rd: PROCESS(r_data_rd, r_op, r_ldst, s_data_addr, r_reg_t, i_data_rd_data, s_val_t)
437 480
         VARIABLE v_b: std_logic_vector( 7 DOWNTO 0);
438 481
         VARIABLE v_h: std_logic_vector(15 DOWNTO 0);
... ...
@@ -35,6 +35,7 @@ ARCHITECTURE a_system OF e_system IS
35 35
     SIGNAL s_instr_data:   std_logic_vector(31 DOWNTO 0);
36 36
     SIGNAL s_dbus_addr:    std_logic_vector(31 DOWNTO 0);
37 37
     SIGNAL s_dbus_rd_data: std_logic_vector(31 DOWNTO 0);
38
+    SIGNAL s_dbus_rd_en:   std_logic_vector( 3 DOWNTO 0);
38 39
     SIGNAL s_dbus_wr_data: std_logic_vector(31 DOWNTO 0);
39 40
     SIGNAL s_dbus_wr_en:   std_logic_vector( 3 DOWNTO 0);
40 41
 
... ...
@@ -54,10 +55,12 @@ ARCHITECTURE a_system OF e_system IS
54 55
     SIGNAL s_switches_rd_data: std_logic_vector(31 DOWNTO 0);
55 56
     SIGNAL s_uart_addr:    std_logic_vector( 3 DOWNTO 0);
56 57
     SIGNAL s_uart_rd_data: std_logic_vector(31 DOWNTO 0);
58
+    SIGNAL s_uart_rd_en:   std_logic_vector( 3 DOWNTO 0);
57 59
     SIGNAL s_uart_wr_data: std_logic_vector(31 DOWNTO 0);
58 60
     SIGNAL s_uart_wr_en:   std_logic_vector( 3 DOWNTO 0);
59 61
     SIGNAL s_eth_addr:    std_logic_vector( 3 DOWNTO 0);
60 62
     SIGNAL s_eth_rd_data: std_logic_vector(31 DOWNTO 0);
63
+    SIGNAL s_eth_rd_en:   std_logic_vector( 3 DOWNTO 0);
61 64
     SIGNAL s_eth_wr_data: std_logic_vector(31 DOWNTO 0);
62 65
     SIGNAL s_eth_wr_en:   std_logic_vector( 3 DOWNTO 0);
63 66
     SIGNAL s_cyc_cnt_rd_data: std_logic_vector(31 DOWNTO 0);
... ...
@@ -73,6 +76,7 @@ ARCHITECTURE a_system OF e_system IS
73 76
             i_instr_data:   IN  std_logic_vector(31 DOWNTO 0);
74 77
             o_data_addr:    OUT std_logic_vector(31 DOWNTO 0);
75 78
             i_data_rd_data: IN  std_logic_vector(31 DOWNTO 0);
79
+            o_data_rd_en:   OUT std_logic_vector( 3 DOWNTO 0);
76 80
             o_data_wr_data: OUT std_logic_vector(31 DOWNTO 0);
77 81
             o_data_wr_en:   OUT std_logic_vector( 3 DOWNTO 0)
78 82
         );
... ...
@@ -179,6 +183,7 @@ ARCHITECTURE a_system OF e_system IS
179 183
             clk:       IN  std_logic;
180 184
             i_addr:    IN  std_logic_vector( 1 DOWNTO 0);
181 185
             o_rd_data: OUT std_logic_vector(31 DOWNTO 0);
186
+            i_rd_en:   IN  std_logic_vector( 3 DOWNTO 0);
182 187
             i_wr_data: IN  std_logic_vector(31 DOWNTO 0);
183 188
             i_wr_en:   IN  std_logic_vector( 3 DOWNTO 0);
184 189
             pin_i_rx:  IN  std_logic;
... ...
@@ -192,6 +197,7 @@ ARCHITECTURE a_system OF e_system IS
192 197
             clk:          IN  std_logic;
193 198
             i_addr:       IN  std_logic_vector( 1 DOWNTO 0);
194 199
             o_rd_data:    OUT std_logic_vector(31 DOWNTO 0);
200
+            i_rd_en:      IN  std_logic_vector( 3 DOWNTO 0);
195 201
             i_wr_data:    IN  std_logic_vector(31 DOWNTO 0);
196 202
             i_wr_en:      IN  std_logic_vector( 3 DOWNTO 0);
197 203
             pin_o_nrst:   OUT std_logic;
... ...
@@ -227,6 +233,7 @@ BEGIN
227 233
             i_instr_data   => s_instr_data,
228 234
             o_data_addr    => s_dbus_addr,
229 235
             i_data_rd_data => s_dbus_rd_data,
236
+            o_data_rd_en   => s_dbus_rd_en,
230 237
             o_data_wr_data => s_dbus_wr_data,
231 238
             o_data_wr_en   => s_dbus_wr_en
232 239
         );
... ...
@@ -281,7 +288,8 @@ BEGIN
281 288
         END IF;
282 289
     END PROCESS p_dbus_rd;
283 290
 
284
-    p_dbus_wr: PROCESS(s_dbus_addr, s_dbus_wr_data, s_dbus_wr_en)
291
+    p_dbus_wr: PROCESS(s_dbus_addr, s_dbus_rd_en,
292
+                       s_dbus_wr_data, s_dbus_wr_en)
285 293
         VARIABLE v_wr_en_word: std_logic;
286 294
     BEGIN
287 295
         v_wr_en_word := s_dbus_wr_en(0) AND s_dbus_wr_en(1) AND
... ...
@@ -295,9 +303,11 @@ BEGIN
295 303
         s_lcd_wr_en   <= (OTHERS => '0');
296 304
         s_switches_addr <= (OTHERS => '0');
297 305
         s_uart_addr    <= (OTHERS => '0');
306
+        s_uart_rd_en   <= (OTHERS => '0');
298 307
         s_uart_wr_data <= (OTHERS => '0');
299 308
         s_uart_wr_en   <= (OTHERS => '0');
300 309
         s_eth_addr    <= (OTHERS => '0');
310
+        s_eth_rd_en   <= (OTHERS => '0');
301 311
         s_eth_wr_data <= (OTHERS => '0');
302 312
         s_eth_wr_en   <= (OTHERS => '0');
303 313
         s_cyc_cnt_wr_data <= (OTHERS => '0');
... ...
@@ -318,10 +328,12 @@ BEGIN
318 328
                     s_switches_addr <= s_dbus_addr(2 DOWNTO 0);
319 329
                 WHEN X"03" =>
320 330
                     s_uart_addr    <= s_dbus_addr(3 DOWNTO 0);
331
+                    s_uart_rd_en   <= s_dbus_rd_en;
321 332
                     s_uart_wr_data <= s_dbus_wr_data;
322 333
                     s_uart_wr_en   <= s_dbus_wr_en;
323 334
                 WHEN X"04" =>
324 335
                     s_eth_addr    <= s_dbus_addr(3 DOWNTO 0);
336
+                    s_eth_rd_en   <= s_dbus_rd_en;
325 337
                     s_eth_wr_data <= s_dbus_wr_data;
326 338
                     s_eth_wr_en   <= s_dbus_wr_en;
327 339
                 WHEN X"10" =>
... ...
@@ -415,6 +427,7 @@ BEGIN
415 427
             clk       => clk,
416 428
             i_addr    => s_uart_addr(3 DOWNTO 2),
417 429
             o_rd_data => s_uart_rd_data,
430
+            i_rd_en   => s_uart_rd_en,
418 431
             i_wr_data => s_uart_wr_data,
419 432
             i_wr_en   => s_uart_wr_en,
420 433
             pin_i_rx  => pin_i_uart_rx,
... ...
@@ -427,6 +440,7 @@ BEGIN
427 440
             clk          => clk,
428 441
             i_addr       => s_eth_addr(3 DOWNTO 2),
429 442
             o_rd_data    => s_eth_rd_data,
443
+            i_rd_en      => s_eth_rd_en,
430 444
             i_wr_data    => s_eth_wr_data,
431 445
             i_wr_en      => s_eth_wr_en,
432 446
             pin_o_nrst   => pin_o_eth_nrst,
433 447