Răsfoiți Sursa

Added signed fixed point multiplication to ALU.

bart 1 an în urmă
părinte
comite
3af9eecaa9

BIN
Quartus/FPGC.qws


+ 23 - 17
Quartus/modules/CPU/ALU.v

@@ -25,27 +25,33 @@ localparam
     OP_LOAD     = 4'b1100, // Load input B ( y := b )
     OP_LOADHI   = 4'b1101, // Loadhi input B ( y := {(b<<16), a} )
     OP_SHIFTRS  = 4'b1110, // Shift right with sign extesion
-    OP_U7       = 4'b1111; // Unimplemented
+    OP_FPMULTS  = 4'b1111; // Fixed point (16.16) signed multiplication
+
+reg signed [63:0] ab; // result for FPMULTS
 
 always @ (*) 
 begin
     case (opcode)
-        OP_OR:      y <= a | b;
-        OP_AND:     y <= a & b;
-        OP_XOR:     y <= a ^ b;
-        OP_ADD:     y <= a + b;
-        OP_SUB:     y <= a - b;
-        OP_SHIFTL:  y <= a << b;
-        OP_SHIFTR:  y <= a >> b;
-        OP_NOTA:    y <= ~a;
-        OP_MULTS:   y <= $signed(a) * $signed(b);
-        OP_MULTU:   y <= a * b;
-        OP_SLT:     y <= {{31{1'b0}}, ($signed(a) < $signed(b))};
-        OP_SLTU:    y <= {{31{1'b0}}, (a < b)};
-        OP_LOAD:    y <= b;
-        OP_LOADHI:  y <= {b[15:0], a[15:0]};
-        OP_SHIFTRS: y <= $signed(a) >>> b;
-        OP_U7:      y <= 32'd0;
+        OP_OR:      y = a | b;
+        OP_AND:     y = a & b;
+        OP_XOR:     y = a ^ b;
+        OP_ADD:     y = a + b;
+        OP_SUB:     y = a - b;
+        OP_SHIFTL:  y = a << b;
+        OP_SHIFTR:  y = a >> b;
+        OP_NOTA:    y = ~a;
+        OP_MULTS:   y = $signed(a) * $signed(b);
+        OP_MULTU:   y = a * b;
+        OP_SLT:     y = {{31{1'b0}}, ($signed(a) < $signed(b))};
+        OP_SLTU:    y = {{31{1'b0}}, (a < b)};
+        OP_LOAD:    y = b;
+        OP_LOADHI:  y = {b[15:0], a[15:0]};
+        OP_SHIFTRS: y = $signed(a) >>> b;
+        OP_FPMULTS:
+        begin
+            ab  = $signed(a) * $signed(b);
+            y   = ab[47:16];
+        end      
     endcase
 end
 

BIN
Quartus/output_files/output_file.jic


+ 23 - 17
Verilog/modules/CPU/ALU.v

@@ -25,27 +25,33 @@ localparam
     OP_LOAD     = 4'b1100, // Load input B ( y := b )
     OP_LOADHI   = 4'b1101, // Loadhi input B ( y := {(b<<16), a} )
     OP_SHIFTRS  = 4'b1110, // Shift right with sign extesion
-    OP_U7       = 4'b1111; // Unimplemented
+    OP_FPMULTS  = 4'b1111; // Fixed point (16.16) signed multiplication
+
+reg signed [63:0] ab; // result for FPMULTS
 
 always @ (*) 
 begin
     case (opcode)
-        OP_OR:      y <= a | b;
-        OP_AND:     y <= a & b;
-        OP_XOR:     y <= a ^ b;
-        OP_ADD:     y <= a + b;
-        OP_SUB:     y <= a - b;
-        OP_SHIFTL:  y <= a << b;
-        OP_SHIFTR:  y <= a >> b;
-        OP_NOTA:    y <= ~a;
-        OP_MULTS:   y <= $signed(a) * $signed(b);
-        OP_MULTU:   y <= a * b;
-        OP_SLT:     y <= {{31{1'b0}}, ($signed(a) < $signed(b))};
-        OP_SLTU:    y <= {{31{1'b0}}, (a < b)};
-        OP_LOAD:    y <= b;
-        OP_LOADHI:  y <= {b[15:0], a[15:0]};
-        OP_SHIFTRS: y <= $signed(a) >>> b;
-        OP_U7:      y <= 32'd0;
+        OP_OR:      y = a | b;
+        OP_AND:     y = a & b;
+        OP_XOR:     y = a ^ b;
+        OP_ADD:     y = a + b;
+        OP_SUB:     y = a - b;
+        OP_SHIFTL:  y = a << b;
+        OP_SHIFTR:  y = a >> b;
+        OP_NOTA:    y = ~a;
+        OP_MULTS:   y = $signed(a) * $signed(b);
+        OP_MULTU:   y = a * b;
+        OP_SLT:     y = {{31{1'b0}}, ($signed(a) < $signed(b))};
+        OP_SLTU:    y = {{31{1'b0}}, (a < b)};
+        OP_LOAD:    y = b;
+        OP_LOADHI:  y = {b[15:0], a[15:0]};
+        OP_SHIFTRS: y = $signed(a) >>> b;
+        OP_FPMULTS:
+        begin
+            ab  = $signed(a) * $signed(b);
+            y   = ab[47:16];
+        end      
     endcase
 end