implemented multiplier
Stefan Schuermans

Stefan Schuermans commited on 2012-02-05 18:33:53
Showing 1 changed files, with 118 additions and 3 deletions.

... ...
@@ -21,6 +21,7 @@ ARCHITECTURE a_mips_core OF e_mips_core IS
21 21
 
22 22
     SIGNAL s_stall:         std_logic;
23 23
     SIGNAL s_stall_data_rd: std_logic;
24
+    SIGNAL s_stall_mul:     std_logic;
24 25
 
25 26
     SIGNAL r_pc: std_logic_vector(31 DOWNTO 0);
26 27
     SIGNAL n_pc: std_logic_vector(31 DOWNTO 0);
... ...
@@ -83,14 +84,25 @@ ARCHITECTURE a_mips_core OF e_mips_core IS
83 84
     SIGNAL s_data_addr: std_logic_vector(31 DOWNTO 0);
84 85
 
85 86
     TYPE t_data_rd IS (data_rd_idle, data_rd_read);
86
-    SIGNAL r_data_rd: t_data_rd;
87 87
     SIGNAL n_data_rd: t_data_rd;
88
+    SIGNAL r_data_rd: t_data_rd;
88 89
 
89 90
     SIGNAL n_reg_lo: std_logic_vector(31 DOWNTO 0);
90 91
     SIGNAL n_reg_hi: std_logic_vector(31 DOWNTO 0);
91 92
     SIGNAL r_reg_lo: std_logic_vector(31 DOWNTO 0);
92 93
     SIGNAL r_reg_hi: std_logic_vector(31 DOWNTO 0);
93 94
 
95
+    TYPE t_mul IS (mul_idle, mul_1, mul_2, mul_3, mul_4, mul_post);
96
+    SIGNAL n_mul: t_mul;
97
+    SIGNAL r_mul: t_mul;
98
+
99
+    SIGNAL n_mul_a:   unsigned(31 DOWNTO 0);
100
+    SIGNAL n_mul_b:   unsigned(31 DOWNTO 0);
101
+    SIGNAL n_mul_res: unsigned(63 DOWNTO 0);
102
+    SIGNAL r_mul_a:   unsigned(31 DOWNTO 0);
103
+    SIGNAL r_mul_b:   unsigned(31 DOWNTO 0);
104
+    SIGNAL r_mul_res: unsigned(63 DOWNTO 0);
105
+
94 106
     COMPONENT e_mips_decoder IS
95 107
         PORT (
96 108
             i_instr:  IN  std_logic_vector(31 DOWNTO 0);
... ...
@@ -143,7 +155,7 @@ ARCHITECTURE a_mips_core OF e_mips_core IS
143 155
 
144 156
 BEGIN
145 157
 
146
-    s_stall <= i_stall OR s_stall_data_rd;
158
+    s_stall <= i_stall OR s_stall_data_rd OR s_stall_mul;
147 159
 
148 160
     decoder: e_mips_decoder
149 161
         PORT MAP (
... ...
@@ -504,7 +516,7 @@ BEGIN
504 516
         END IF;
505 517
     END PROCESS p_data_wr;
506 518
 
507
-    p_reg_hi_lo: PROCESS(r_reg_lo, r_reg_hi, r_op, r_reg_d, s_val_s)
519
+    p_reg_hi_lo: PROCESS(r_reg_lo, r_reg_hi, r_op, r_reg_d, s_val_s, r_mul_res)
508 520
     BEGIN
509 521
         n_reg_lo            <= r_reg_lo;
510 522
         n_reg_hi            <= r_reg_hi;
... ...
@@ -524,6 +536,9 @@ BEGIN
524 536
                 n_reg_hi <= s_val_s;
525 537
             WHEN op_mtlo =>
526 538
                 n_reg_lo <= s_val_s;
539
+            WHEN op_mult | op_multu =>
540
+                n_reg_lo <= std_logic_vector(r_mul_res(31 DOWNTO  0));
541
+                n_reg_hi <= std_logic_vector(r_mul_res(63 DOWNTO 32));
527 542
             WHEN OTHERS => NULL;
528 543
         END CASE;
529 544
     END PROCESS p_reg_hi_lo;
... ...
@@ -541,4 +556,104 @@ BEGIN
541 556
         END IF;
542 557
     END PROCESS p_sync_reg_hi_lo;
543 558
 
559
+    p_mul: PROCESS(r_mul, r_mul_a, r_mul_b, r_mul_res, r_op, s_val_s, s_val_t)
560
+        VARIABLE v_a:   unsigned(15 DOWNTO 0);
561
+        VARIABLE v_b:   unsigned(15 DOWNTO 0);
562
+        VARIABLE v_res: unsigned(31 DOWNTO 0);
563
+        VARIABLE v_add: unsigned(63 DOWNTO 0);
564
+        VARIABLE v_sum: unsigned(63 DOWNTO 0);
565
+    BEGIN
566
+        s_stall_mul <= '0';
567
+        n_mul       <= mul_idle;
568
+        n_mul_a     <= r_mul_a;
569
+        n_mul_b     <= r_mul_b;
570
+        n_mul_res   <= r_mul_res;
571
+        v_a         := (OTHERS => '0');
572
+        v_b         := (OTHERS => '0');
573
+        v_add       := (OTHERS => '0');
574
+        CASE r_mul IS
575
+            WHEN mul_idle =>
576
+                CASE r_op IS
577
+                    WHEN op_mult =>
578
+                        s_stall_mul <= '1';
579
+                        n_mul       <= mul_1;
580
+                        IF s_val_s(31) = '1' THEN
581
+                            n_mul_a <= unsigned(-signed(s_val_s));
582
+                        ELSE
583
+                            n_mul_a <= unsigned(s_val_s);
584
+                        END IF;
585
+                        IF s_val_t(31) = '1' THEN
586
+                            n_mul_b <= unsigned(-signed(s_val_t));
587
+                        ELSE
588
+                            n_mul_b <= unsigned(s_val_t);
589
+                        END IF;
590
+                        n_mul_res <= (OTHERS => '0');
591
+                    WHEN op_multu =>
592
+                        s_stall_mul <= '1';
593
+                        n_mul       <= mul_1;
594
+                        n_mul_a     <= unsigned(s_val_s);
595
+                        n_mul_b     <= unsigned(s_val_t);
596
+                    WHEN OTHERS => NULL;
597
+                END CASE;
598
+            WHEN mul_1 =>
599
+                s_stall_mul <= '1';
600
+                n_mul       <= mul_2;
601
+                v_a         := r_mul_a(15 DOWNTO  0);
602
+                v_b         := r_mul_b(15 DOWNTO  0);
603
+            WHEN mul_2 =>
604
+                s_stall_mul <= '1';
605
+                n_mul       <= mul_3;
606
+                v_a         := r_mul_a(31 DOWNTO 16);
607
+                v_b         := r_mul_b(15 DOWNTO  0);
608
+            WHEN mul_3 =>
609
+                s_stall_mul <= '1';
610
+                n_mul       <= mul_4;
611
+                v_a         := r_mul_a(15 DOWNTO  0);
612
+                v_b         := r_mul_b(31 DOWNTO 16);
613
+            WHEN mul_4 =>
614
+                s_stall_mul <= '1';
615
+                n_mul       <= mul_post;
616
+                v_a         := r_mul_a(31 DOWNTO 16);
617
+                v_b         := r_mul_b(31 DOWNTO 16);
618
+            WHEN OTHERS => NULL;
619
+        END CASE;
620
+        v_res := v_a * v_b;
621
+        CASE r_mul IS
622
+            WHEN mul_1 => v_add := X"00000000" & v_res;
623
+            WHEN mul_2 => v_add := X"0000" & v_res & X"0000";
624
+            WHEN mul_3 => v_add := X"0000" & v_res & X"0000";
625
+            WHEN mul_4 => v_add := v_res & X"00000000";
626
+            WHEN OTHERS => NULL;
627
+        END CASE;
628
+        v_sum := r_mul_res + v_add;
629
+        CASE r_mul IS
630
+            WHEN mul_1 | mul_2 | mul_3 | mul_4 =>
631
+                n_mul_res <= v_sum;
632
+            WHEN mul_post =>
633
+                IF r_op = op_mult AND (s_val_s(31) = '1' XOR s_val_t(31) = '1') THEN
634
+                    n_mul_res <= unsigned(-signed(r_mul_res));
635
+                ELSE
636
+                    n_mul_res <= r_mul_res;
637
+                END IF;
638
+            WHEN OTHERS => NULL;
639
+        END CASE;
640
+    END PROCESS p_mul;
641
+
642
+    p_sync_mul: PROCESS(rst, clk)
643
+    BEGIN
644
+        IF rst = '1' THEN
645
+            r_mul     <= mul_idle;
646
+            r_mul_a   <= (OTHERS => '0');
647
+            r_mul_b   <= (OTHERS => '0');
648
+            r_mul_res <= (OTHERS => '0');
649
+        ELSIF rising_edge(clk) THEN
650
+            IF i_stall = '0' THEN
651
+                r_mul     <= n_mul;
652
+                r_mul_a   <= n_mul_a;
653
+                r_mul_b   <= n_mul_b;
654
+                r_mul_res <= n_mul_res;
655
+            END IF;
656
+        END IF;
657
+    END PROCESS p_sync_mul;
658
+
544 659
 END ARCHITECTURE a_mips_core;
545 660