| `default_nettype none |
| |
| // Keep I/O fixed for TinyTapeout |
| module user_module_341176884318437971( |
| input wire [7:0] io_in, |
| output wire [7:0] io_out |
| ); |
| /* |
| * Local signals |
| */ |
| // Used as a clock. |
| wire clk; |
| |
| // Used as a synchronous reset. |
| wire rst; |
| |
| // Indicates that the first nibble is registered. |
| reg int_nibble_stored; |
| |
| // The registered first nibble. |
| reg [3:0] int_first_nibble; |
| |
| // The resistered output. |
| reg [7:0] int_out; |
| |
| // The multiplied 8-bit output. |
| wire [7:0] int_mult_result; |
| /* |
| * Logic |
| */ |
| // Using io_in[0] as clk. |
| assign clk = io_in[0]; |
| |
| // Using io_in[1] as rst. |
| assign rst = io_in[1]; |
| |
| // Assign the |
| assign io_out = int_out; |
| |
| always @(posedge clk) begin |
| if (rst) begin |
| int_nibble_stored <= 1'b0; |
| int_first_nibble <= 4'd0; |
| int_out <= 8'd0; |
| end else begin |
| // If we havent latched in the first nibble, |
| // then do so first. |
| if (!int_nibble_stored) begin |
| int_first_nibble <= io_in[7:4]; |
| int_nibble_stored <= 1'b1; |
| end else begin |
| // Register the multiplier result. |
| int_out <= int_mult_result; |
| |
| // Reset the nibble registered flag. |
| int_nibble_stored <= 1'b0; |
| |
| // Reset the nibble data. |
| int_first_nibble <= 4'd0; |
| end |
| end |
| end |
| |
| /* |
| * Instances |
| */ |
| Mult_Wallace4_341176884318437971 inst_mul ( |
| .a(int_first_nibble), |
| .b(io_in[7:4]), |
| .o(int_mult_result) |
| ); |
| endmodule |
| |
| // Unsigned 4x4-bit multiplier with |
| // Wallace tree reduction. Generated |
| // with my own tool. |
| module Mult_Wallace4_341176884318437971 # ( |
| parameter N = 4 |
| )( |
| input wire [N-1:0] a, |
| input wire [N-1:0] b, |
| output wire [2*N-1:0] o |
| ); |
| |
| wire [N-1:0] ppts[N-1:0]; |
| |
| assign ppts[0][0] = a[0] & b[0]; |
| assign ppts[0][1] = a[0] & b[1]; |
| assign ppts[0][2] = a[0] & b[2]; |
| assign ppts[0][3] = a[0] & b[3]; |
| assign ppts[1][0] = a[1] & b[0]; |
| assign ppts[1][1] = a[1] & b[1]; |
| assign ppts[1][2] = a[1] & b[2]; |
| assign ppts[1][3] = a[1] & b[3]; |
| assign ppts[2][0] = a[2] & b[0]; |
| assign ppts[2][1] = a[2] & b[1]; |
| assign ppts[2][2] = a[2] & b[2]; |
| assign ppts[2][3] = a[2] & b[3]; |
| assign ppts[3][0] = a[3] & b[0]; |
| assign ppts[3][1] = a[3] & b[1]; |
| assign ppts[3][2] = a[3] & b[2]; |
| assign ppts[3][3] = a[3] & b[3]; |
| |
| wire [11:0] s; |
| wire [11:0] cout; |
| |
| ha_341176884318437971 HA1 (.a(ppts[0][1]), .b(ppts[1][0]), .s(s[0]), .cout(cout[0])); |
| fa_341176884318437971 FA2 (.a(ppts[0][2]), .b(ppts[1][1]), .cin(ppts[2][0]), .s(s[1]), .cout(cout[1])); |
| fa_341176884318437971 FA3 (.a(ppts[0][3]), .b(ppts[1][2]), .cin(ppts[2][1]), .s(s[2]), .cout(cout[2])); |
| ha_341176884318437971 HA4 (.a(ppts[1][3]), .b(ppts[2][2]), .s(s[3]), .cout(cout[3])); |
| ha_341176884318437971 HA5 (.a(cout[0]), .b(s[1]), .s(s[4]), .cout(cout[4])); |
| fa_341176884318437971 FA6 (.a(ppts[3][0]), .b(cout[1]), .cin(s[2]), .s(s[5]), .cout(cout[5])); |
| fa_341176884318437971 FA7 (.a(ppts[3][1]), .b(cout[2]), .cin(s[3]), .s(s[6]), .cout(cout[6])); |
| fa_341176884318437971 FA8 (.a(ppts[2][3]), .b(ppts[3][2]), .cin(cout[3]), .s(s[7]), .cout(cout[7])); |
| ha_341176884318437971 HA9 (.a(cout[4]), .b(s[5]), .s(s[8]), .cout(cout[8])); |
| fa_341176884318437971 FA10 (.a(cout[5]), .b(s[6]), .cin(cout[8]), .s(s[9]), .cout(cout[9])); |
| fa_341176884318437971 FA11 (.a(cout[6]), .b(s[7]), .cin(cout[9]), .s(s[10]), .cout(cout[10])); |
| fa_341176884318437971 FA12 (.a(ppts[3][3]), .b(cout[7]), .cin(cout[10]), .s(s[11]), .cout(cout[11])); |
| |
| assign o[7] = cout[11]; |
| assign o[6] = s[11]; |
| assign o[5] = s[10]; |
| assign o[4] = s[9]; |
| assign o[3] = s[8]; |
| assign o[2] = s[4]; |
| assign o[1] = s[0]; |
| assign o[0] = ppts[0][0]; |
| endmodule |
| |
| // Full adder |
| module fa_341176884318437971 ( |
| input wire a, |
| input wire b, |
| input wire cin, |
| output wire s, |
| output wire cout |
| ); |
| |
| /* |
| * Local signals |
| */ |
| // wire int_a_xor_b; |
| // wire int_a_and_b; |
| // wire int_a_xor_b_and_cin; |
| /* |
| * Logic |
| */ |
| |
| // Implement a full adder with individual gates. |
| // assign int_a_xor_b = a ^ b; |
| // assign int_a_and_b = a & b; |
| // assign int_a_xor_b_and_cin = int_a_xor_b & cin; |
| // assign s = int_a_xor_b ^ cin; |
| // assign cout = int_a_xor_b_and_cin | int_a_and_b; |
| |
| // Instantiate a full adder cell from the |
| // standard cell library. |
| // sky130_fd_sc_hd__fah inst_fa ( |
| // .A (a), |
| // .B (b), |
| // .CI (cin), |
| // .SUM (s), |
| // .COUT(cout) |
| // ); |
| |
| // Infer a full adder. |
| assign {cout, s} = a + b + cin; |
| endmodule |
| |
| // Half adder |
| module ha_341176884318437971 ( |
| input wire a, |
| input wire b, |
| output wire s, |
| output wire cout |
| ); |
| |
| /* |
| * Logic |
| */ |
| |
| // Implement a half adder with individual gates. |
| // assign s = a ^ b; |
| // assign cout = a & b; |
| |
| // Instantiate a half adder cell from the |
| // standard cell library. |
| // sky130_fd_sc_hd__ha inst_ha ( |
| // .A (a), |
| // .B (b), |
| // .SUM (s), |
| // .COUT(cout) |
| // ); |
| |
| // Infer a half adder. |
| assign {cout, s} = a + b; |
| endmodule |
| |
| // Carry save adder |
| module csa_341176884318437971 #( |
| parameter NUM_BITS = 4 |
| ) ( |
| input wire [NUM_BITS-1:0] a, // Input A |
| input wire [NUM_BITS-1:0] b, // Input B |
| input wire [NUM_BITS-1:0] c, // Input C |
| output wire [NUM_BITS-1:0] p, // Output p (propagate) |
| output wire [NUM_BITS-1:0] g // Output g (generate) |
| ); |
| genvar i; |
| |
| generate |
| for (i = 0; i < NUM_BITS; i = i + 1) begin |
| fa_341176884318437971 fa_i ( |
| .a (a[i]), |
| .b (b[i]), |
| .cin (c[i]), |
| .s (p[i]), |
| .cout(g[i]) |
| ); |
| end |
| endgenerate |
| endmodule |
| |
| // Ripple carry adder |
| module rca_341176884318437971 #( |
| parameter NUM_BITS = 4 |
| ) ( |
| input wire [NUM_BITS-1:0] a, |
| input wire [NUM_BITS-1:0] b, |
| output wire [NUM_BITS-1:0] s, |
| output wire cout |
| ); |
| |
| /* |
| * Local signals |
| */ |
| // The carry out to carry in signals. |
| wire [NUM_BITS:0] int_carry; |
| |
| /* |
| * Logic |
| */ |
| genvar i; |
| |
| generate |
| for (i = 0; i < NUM_BITS; i = i + 1) begin |
| if (i == 0) begin |
| // The first bits have no carry in, |
| // so just generate a half adder. |
| ha_341176884318437971 ha_0 ( |
| .a (a[i]), |
| .b (b[i]), |
| .s (s[i]), |
| .cout(int_carry[i]) |
| ); |
| end else begin |
| fa_341176884318437971 fa_i ( |
| .a (a[i]), |
| .b (b[i]), |
| .cin (int_carry[i-1]), |
| .s (s[i]), |
| .cout(int_carry[i]) |
| ); |
| end |
| end |
| endgenerate |
| |
| assign cout = int_carry[NUM_BITS-1]; |
| endmodule |