├── .gitignore ├── 74_adder.v ├── 74_cmp.v ├── 74_counter.v ├── 74_dffe.v ├── 74_eq.v ├── 74_extract.il ├── 74_extract.v ├── 74_models.v ├── 74_mux.v ├── 74ac.lib ├── benchmarks ├── VexRiscv.v ├── arlet_6502.v ├── arlet_6502_alu.v ├── axilxbar.v ├── cic5.v ├── cic5_tb.v ├── cordic_10_16.v ├── counter.v ├── counter_tb.v ├── dspmac_16_40.v ├── dspmac_16_40_tb.v ├── picorv32.v ├── picorv32_tb.v ├── pwm256.v ├── pwm256_tb.v ├── pwmled.v ├── pwmled_tb.v ├── sddac.v ├── sddac_tb.v ├── shifter64.v └── smartbextdep.v ├── bram.rules ├── equiv.ys ├── ic_count.py ├── kicad ├── 74xx.dcm ├── 74xx.lib ├── Makefile ├── generate_netlist.py └── parts.py ├── po74g.lib ├── sim └── Makefile ├── stat └── Makefile └── synth_74.ys /.gitignore: -------------------------------------------------------------------------------- 1 | stat/*.stat 2 | sim/*.v 3 | sim/*.vcd 4 | sim/*.vvp 5 | -------------------------------------------------------------------------------- /74_adder.v: -------------------------------------------------------------------------------- 1 | (* techmap_celltype = "$add" *) 2 | module _80_74AC283_add (A, B, Y); 3 | 4 | parameter A_SIGNED = 0; 5 | parameter B_SIGNED = 0; 6 | parameter A_WIDTH = 4; 7 | parameter B_WIDTH = 4; 8 | parameter Y_WIDTH = 4; 9 | 10 | input [A_WIDTH-1:0] A; 11 | input [B_WIDTH-1:0] B; 12 | output [Y_WIDTH-1:0] Y; 13 | 14 | wire _TECHMAP_FAIL_ = Y_WIDTH <= 1; 15 | 16 | localparam WIDTH = ((Y_WIDTH + 3) / 4) * 4; 17 | 18 | wire [Y_WIDTH-1:0] A_buf, B_buf; 19 | \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); 20 | \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); 21 | 22 | wire [WIDTH-1:0] AA = A_buf; 23 | wire [WIDTH-1:0] BB = B_buf; 24 | wire [WIDTH-1:0] YY; 25 | wire [WIDTH:0] C; 26 | 27 | assign C[0] = 0; 28 | 29 | genvar i; 30 | generate for (i = 0; i < WIDTH; i = i + 4) begin:slice 31 | \74AC283_1x1ADD4 adder_i( 32 | .A(AA[i+3:i]), 33 | .B(BB[i+3:i]), 34 | .CI(C[i]), 35 | .S(YY[i+3:i]), 36 | .CO(C[i+4]), 37 | ); 38 | end 39 | endgenerate 40 | 41 | assign Y = YY[Y_WIDTH-1:0]; 42 | 43 | endmodule 44 | 45 | (* techmap_celltype = "$sub" *) 46 | module _80_74AC283_sub (A, B, Y); 47 | 48 | parameter A_SIGNED = 0; 49 | parameter B_SIGNED = 0; 50 | parameter A_WIDTH = 4; 51 | parameter B_WIDTH = 4; 52 | parameter Y_WIDTH = 4; 53 | 54 | input [A_WIDTH-1:0] A; 55 | input [B_WIDTH-1:0] B; 56 | output [Y_WIDTH-1:0] Y; 57 | 58 | wire _TECHMAP_FAIL_ = Y_WIDTH <= 1; 59 | 60 | localparam WIDTH = ((Y_WIDTH + 3) / 4) * 4; 61 | 62 | wire [Y_WIDTH-1:0] A_buf, B_buf; 63 | \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); 64 | \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); 65 | 66 | wire [WIDTH-1:0] AA = A_buf; 67 | wire [WIDTH-1:0] BB = B_buf; 68 | wire [WIDTH-1:0] YY; 69 | wire [WIDTH:0] C; 70 | 71 | assign C[0] = 1; 72 | 73 | genvar i; 74 | generate for (i = 0; i < WIDTH; i = i + 4) begin:slice 75 | \74AC283_1x1ADD4 adder_i ( 76 | .A(AA[i+3:i]), 77 | .B(~BB[i+3:i]), 78 | .CI(C[i]), 79 | .S(YY[i+3:i]), 80 | .CO(C[i+4]), 81 | ); 82 | end 83 | endgenerate 84 | 85 | assign Y = YY[Y_WIDTH-1:0]; 86 | 87 | endmodule 88 | -------------------------------------------------------------------------------- /74_cmp.v: -------------------------------------------------------------------------------- 1 | (* techmap_celltype = "$lt" *) 2 | module _80_74HC85_lt (A, B, Y); 3 | 4 | parameter A_SIGNED = 0; 5 | parameter B_SIGNED = 0; 6 | parameter A_WIDTH = 0; 7 | parameter B_WIDTH = 0; 8 | parameter Y_WIDTH = 0; 9 | 10 | input [A_WIDTH-1:0] A; 11 | input [B_WIDTH-1:0] B; 12 | output [Y_WIDTH-1:0] Y; 13 | 14 | wire _TECHMAP_FAIL_ = A_WIDTH <= 3 && B_WIDTH <= 3; 15 | 16 | localparam MAX_WIDTH = (A_WIDTH > B_WIDTH) ? A_WIDTH : B_WIDTH; 17 | localparam WIDTH = ((MAX_WIDTH + 3) / 4) * 4; 18 | 19 | wire [MAX_WIDTH-1:0] A_buf, B_buf; 20 | \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(MAX_WIDTH)) A_conv (.A(A), .Y(A_buf)); 21 | \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(MAX_WIDTH)) B_conv (.A(B), .Y(B_buf)); 22 | 23 | wire [WIDTH-1:0] AA = A_buf; 24 | wire [WIDTH-1:0] BB = B_buf; 25 | wire [WIDTH:0] G; 26 | wire [WIDTH:0] E; 27 | wire [WIDTH:0] L; 28 | 29 | assign G[0] = 0; 30 | assign E[0] = 1; 31 | assign L[0] = 0; 32 | 33 | genvar i; 34 | generate for (i = 0; i < WIDTH; i = i + 4) begin:slice 35 | \74HC85_1x1CMP4 cmp_i( 36 | .A(AA[i+3:i]), 37 | .B(BB[i+3:i]), 38 | .Li(L[i]), 39 | .Ei(E[i]), 40 | .Gi(G[i]), 41 | .Lo(L[i+4]), 42 | .Eo(E[i+4]), 43 | .Go(G[i+4]) 44 | ); 45 | end 46 | endgenerate 47 | 48 | assign Y = L[WIDTH]; 49 | 50 | endmodule 51 | 52 | (* techmap_celltype = "$gt" *) 53 | module _80_74HC85_gt (A, B, Y); 54 | 55 | parameter A_SIGNED = 0; 56 | parameter B_SIGNED = 0; 57 | parameter A_WIDTH = 0; 58 | parameter B_WIDTH = 0; 59 | parameter Y_WIDTH = 0; 60 | 61 | input [A_WIDTH-1:0] A; 62 | input [B_WIDTH-1:0] B; 63 | output [Y_WIDTH-1:0] Y; 64 | 65 | wire _TECHMAP_FAIL_ = A_WIDTH <= 3 && B_WIDTH <= 3; 66 | localparam MAX_WIDTH = (A_WIDTH > B_WIDTH) ? A_WIDTH : B_WIDTH; 67 | localparam WIDTH = ((MAX_WIDTH + 3) / 4) * 4; 68 | 69 | wire [MAX_WIDTH-1:0] A_buf, B_buf; 70 | \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(MAX_WIDTH)) A_conv (.A(A), .Y(A_buf)); 71 | \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(MAX_WIDTH)) B_conv (.A(B), .Y(B_buf)); 72 | 73 | wire [WIDTH-1:0] AA = A_buf; 74 | wire [WIDTH-1:0] BB = B_buf; 75 | wire [WIDTH:0] G; 76 | wire [WIDTH:0] E; 77 | wire [WIDTH:0] L; 78 | 79 | assign G[0] = 0; 80 | assign E[0] = 1; 81 | assign L[0] = 0; 82 | 83 | genvar i; 84 | generate for (i = 0; i < WIDTH; i = i + 4) begin:slice 85 | \74HC85_1x1CMP4 cmp_i( 86 | .A(AA[i+3:i]), 87 | .B(BB[i+3:i]), 88 | .Li(L[i]), 89 | .Ei(E[i]), 90 | .Gi(G[i]), 91 | .Lo(L[i+4]), 92 | .Eo(E[i+4]), 93 | .Go(G[i+4]) 94 | ); 95 | end 96 | endgenerate 97 | 98 | assign Y = G[WIDTH]; 99 | 100 | endmodule 101 | 102 | (* techmap_celltype = "$le" *) 103 | module _80_74HC85_le (A, B, Y); 104 | 105 | parameter A_SIGNED = 0; 106 | parameter B_SIGNED = 0; 107 | parameter A_WIDTH = 0; 108 | parameter B_WIDTH = 0; 109 | parameter Y_WIDTH = 0; 110 | 111 | input [A_WIDTH-1:0] A; 112 | input [B_WIDTH-1:0] B; 113 | output [Y_WIDTH-1:0] Y; 114 | 115 | wire _TECHMAP_FAIL_ = A_WIDTH <= 3 && B_WIDTH <= 3; 116 | localparam MAX_WIDTH = (A_WIDTH > B_WIDTH) ? A_WIDTH : B_WIDTH; 117 | localparam WIDTH = ((MAX_WIDTH + 3) / 4) * 4; 118 | 119 | wire [MAX_WIDTH-1:0] A_buf, B_buf; 120 | \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(MAX_WIDTH)) A_conv (.A(A), .Y(A_buf)); 121 | \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(MAX_WIDTH)) B_conv (.A(B), .Y(B_buf)); 122 | 123 | wire [WIDTH-1:0] AA = A_buf; 124 | wire [WIDTH-1:0] BB = B_buf; 125 | wire [WIDTH:0] G; 126 | wire [WIDTH:0] E; 127 | wire [WIDTH:0] L; 128 | 129 | assign G[0] = 0; 130 | assign E[0] = 1; 131 | assign L[0] = 0; 132 | 133 | genvar i; 134 | generate for (i = 0; i < WIDTH; i = i + 4) begin:slice 135 | \74HC85_1x1CMP4 cmp_i( 136 | .A(AA[i+3:i]), 137 | .B(BB[i+3:i]), 138 | .Li(L[i]), 139 | .Ei(E[i]), 140 | .Gi(G[i]), 141 | .Lo(L[i+4]), 142 | .Eo(E[i+4]), 143 | .Go(G[i+4]) 144 | ); 145 | end 146 | endgenerate 147 | 148 | assign Y = !G[WIDTH]; 149 | 150 | endmodule 151 | 152 | (* techmap_celltype = "$ge" *) 153 | module _80_74HC85_ge (A, B, Y); 154 | 155 | parameter A_SIGNED = 0; 156 | parameter B_SIGNED = 0; 157 | parameter A_WIDTH = 0; 158 | parameter B_WIDTH = 0; 159 | parameter Y_WIDTH = 0; 160 | 161 | input [A_WIDTH-1:0] A; 162 | input [B_WIDTH-1:0] B; 163 | output [Y_WIDTH-1:0] Y; 164 | 165 | wire _TECHMAP_FAIL_ = A_WIDTH <= 3 && B_WIDTH <= 3; 166 | localparam MAX_WIDTH = (A_WIDTH > B_WIDTH) ? A_WIDTH : B_WIDTH; 167 | localparam WIDTH = ((MAX_WIDTH + 3) / 4) * 4; 168 | 169 | wire [MAX_WIDTH-1:0] A_buf, B_buf; 170 | \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(MAX_WIDTH)) A_conv (.A(A), .Y(A_buf)); 171 | \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(MAX_WIDTH)) B_conv (.A(B), .Y(B_buf)); 172 | 173 | wire [WIDTH-1:0] AA = A_buf; 174 | wire [WIDTH-1:0] BB = B_buf; 175 | wire [WIDTH:0] G; 176 | wire [WIDTH:0] E; 177 | wire [WIDTH:0] L; 178 | 179 | assign G[0] = 0; 180 | assign E[0] = 1; 181 | assign L[0] = 0; 182 | 183 | genvar i; 184 | generate for (i = 0; i < WIDTH; i = i + 4) begin:slice 185 | \74HC85_1x1CMP4 cmp_i( 186 | .A(AA[i+3:i]), 187 | .B(BB[i+3:i]), 188 | .Li(L[i]), 189 | .Ei(E[i]), 190 | .Gi(G[i]), 191 | .Lo(L[i+4]), 192 | .Eo(E[i+4]), 193 | .Go(G[i+4]) 194 | ); 195 | end 196 | endgenerate 197 | 198 | assign Y = !L[WIDTH]; 199 | 200 | endmodule 201 | -------------------------------------------------------------------------------- /74_counter.v: -------------------------------------------------------------------------------- 1 | (* techmap_celltype = "_74xx_counter8 _74xx_counter16 _74xx_counter32" *) 2 | module _80_74AC161_counter (rst, clk, preset, counter); 3 | parameter _TECHMAP_CELLTYPE_ = ""; 4 | parameter WIDTH = (_TECHMAP_CELLTYPE_ == "_74xx_counter8") ? 8 : (_TECHMAP_CELLTYPE_ == "_74xx_counter16" ? 16 : 32) ; 5 | 6 | input rst; 7 | input clk; 8 | input [WIDTH-1:0] preset; 9 | output reg [WIDTH-1:0] counter; 10 | 11 | wire [WIDTH:0] C; 12 | assign C[0] = 1'b1; 13 | 14 | genvar i; 15 | generate for (i = 0; i < WIDTH; i = i + 4) begin:slice 16 | \74AC161_1x1COUNT4 counter_i( 17 | .A(preset[i+3:i]), 18 | .Q(counter[i+3:i]), 19 | .CLK(clk), 20 | .ENT(C[i]), 21 | .RCO(C[i+4]), 22 | .LOAD(rst) 23 | ); 24 | end 25 | endgenerate 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /74_dffe.v: -------------------------------------------------------------------------------- 1 | module \$_DFFE_PP_ (input D, C, E, output Q); \74AC377_8x1DFFE _TECHMAP_REPLACE_(.D(D), .CP(C), .CE(!E), .Q(Q)); endmodule 2 | module \$_DFFE_PN_ (input D, C, E, output Q); \74AC377_8x1DFFE _TECHMAP_REPLACE_(.D(D), .CP(C), .CE(E), .Q(Q)); endmodule 3 | module \$_DFFE_NP_ (input D, C, E, output Q); \74AC377_8x1DFFE _TECHMAP_REPLACE_(.D(D), .CP(!C), .CE(!E), .Q(Q)); endmodule 4 | module \$_DFFE_NN_ (input D, C, E, output Q); \74AC377_8x1DFFE _TECHMAP_REPLACE_(.D(D), .CP(!C), .CE(E), .Q(Q)); endmodule 5 | -------------------------------------------------------------------------------- /74_eq.v: -------------------------------------------------------------------------------- 1 | // Note: this file is kept around for posterity; ABC is very good at 2 | // optimising equality checks. 3 | 4 | (* techmap_celltype = "$eq" *) 5 | module _80_74HC688_eq (A, B, Y); 6 | 7 | parameter A_SIGNED = 0; 8 | parameter B_SIGNED = 0; 9 | parameter A_WIDTH = 0; 10 | parameter B_WIDTH = 0; 11 | parameter Y_WIDTH = 0; 12 | parameter _TECHMAP_CONSTMSK_A_ = 0; 13 | parameter _TECHMAP_CONSTVAL_A_ = 0; 14 | parameter _TECHMAP_CONSTMSK_B_ = 0; 15 | parameter _TECHMAP_CONSTVAL_B_ = 0; 16 | 17 | input [A_WIDTH-1:0] A; 18 | input [B_WIDTH-1:0] B; 19 | output [Y_WIDTH-1:0] Y; 20 | 21 | wire _TECHMAP_FAIL_ = (A_WIDTH <= 6 && B_WIDTH <= 6) || &_TECHMAP_CONSTMSK_A_ || &_TECHMAP_CONSTMSK_B_; 22 | 23 | localparam WIDTH = ((Y_WIDTH + 7) / 8) * 8; 24 | 25 | wire [Y_WIDTH-1:0] A_buf, B_buf; 26 | \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); 27 | \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); 28 | 29 | wire [WIDTH-1:0] AA = A_buf; 30 | wire [WIDTH-1:0] BB = B_buf; 31 | wire [WIDTH-1:0] YY; 32 | wire [WIDTH:0] C; 33 | 34 | assign C[0] = 0; 35 | 36 | genvar i; 37 | generate for (i = 0; i < WIDTH; i = i + 8) begin:slice 38 | \74HC688_1x1EQ8 eq_i ( 39 | .A(AA[i+7:i]), 40 | .B(BB[i+7:i]), 41 | .E(C[i]), 42 | .Q(C[i+8]) 43 | ); 44 | end 45 | endgenerate 46 | 47 | assign Y = !C[WIDTH]; 48 | 49 | endmodule 50 | 51 | (* techmap_celltype = "$ne" *) 52 | module _80_74HC688_ne (A, B, Y); 53 | 54 | parameter A_SIGNED = 0; 55 | parameter B_SIGNED = 0; 56 | parameter A_WIDTH = 0; 57 | parameter B_WIDTH = 0; 58 | parameter Y_WIDTH = 0; 59 | parameter _TECHMAP_CONSTMSK_A_ = 0; 60 | parameter _TECHMAP_CONSTVAL_A_ = 0; 61 | parameter _TECHMAP_CONSTMSK_B_ = 0; 62 | parameter _TECHMAP_CONSTVAL_B_ = 0; 63 | 64 | input [A_WIDTH-1:0] A; 65 | input [B_WIDTH-1:0] B; 66 | output [Y_WIDTH-1:0] Y; 67 | 68 | wire _TECHMAP_FAIL_ = (A_WIDTH <= 6 && B_WIDTH <= 6) || &_TECHMAP_CONSTMSK_A_ || &_TECHMAP_CONSTMSK_B_; 69 | 70 | localparam WIDTH = ((Y_WIDTH + 7) / 8) * 8; 71 | 72 | wire [Y_WIDTH-1:0] A_buf, B_buf; 73 | \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); 74 | \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); 75 | 76 | wire [WIDTH-1:0] AA = A_buf; 77 | wire [WIDTH-1:0] BB = B_buf; 78 | wire [WIDTH-1:0] YY; 79 | wire [WIDTH:0] C; 80 | 81 | assign C[0] = 0; 82 | 83 | genvar i; 84 | generate for (i = 0; i < WIDTH; i = i + 8) begin:slice 85 | \74HC688_1x1EQ8 eq_i ( 86 | .A(AA[i+7:i]), 87 | .B(BB[i+7:i]), 88 | .E(C[i]), 89 | .Q(C[i+8]) 90 | ); 91 | end 92 | endgenerate 93 | 94 | assign Y = C[WIDTH]; 95 | 96 | endmodule 97 | -------------------------------------------------------------------------------- /74_extract.il: -------------------------------------------------------------------------------- 1 | 2 | autoidx 22 3 | 4 | attribute \cells_not_processed 1 5 | attribute \src "74_extract.v:16" 6 | module \_74xx_counter16 7 | 8 | attribute \src "74_extract.v:22" 9 | wire width 16 $0\counter[15:0] 10 | 11 | attribute \src "74_extract.v:26" 12 | wire width 16 $add$74_extract.v:26$6_Y 13 | 14 | attribute \src "74_extract.v:18" 15 | wire input 2 \clk 16 | 17 | attribute \src "74_extract.v:20" 18 | wire width 16 output 4 \counter 19 | 20 | attribute \src "74_extract.v:19" 21 | wire width 16 input 3 \preset 22 | 23 | attribute \src "74_extract.v:17" 24 | wire input 1 \rst 25 | 26 | attribute \src "74_extract.v:26" 27 | cell $add $add$74_extract.v:26$6 28 | parameter \A_SIGNED 0 29 | parameter \A_WIDTH 16 30 | parameter \B_SIGNED 0 31 | parameter \B_WIDTH 1 32 | parameter \Y_WIDTH 16 33 | connect \A \counter 34 | connect \B 1'1 35 | connect \Y $add$74_extract.v:26$6_Y 36 | end 37 | 38 | attribute \src "74_extract.v:22" 39 | cell $dff $procdff$20 40 | parameter \CLK_POLARITY 1'1 41 | parameter \WIDTH 16 42 | connect \CLK \clk 43 | connect \D $0\counter[15:0] 44 | connect \Q \counter 45 | end 46 | 47 | attribute \full_case 1 48 | attribute \src "74_extract.v:23" 49 | cell $mux $procmux$14 50 | parameter \WIDTH 16 51 | connect \A \preset 52 | connect \B $add$74_extract.v:26$6_Y 53 | connect \S \rst 54 | connect \Y $0\counter[15:0] 55 | end 56 | end 57 | 58 | attribute \cells_not_processed 1 59 | attribute \src "74_extract.v:31" 60 | module \_74xx_counter32 61 | 62 | attribute \src "74_extract.v:37" 63 | wire width 32 $0\counter[31:0] 64 | 65 | attribute \src "74_extract.v:41" 66 | wire width 32 $add$74_extract.v:41$9_Y 67 | 68 | attribute \src "74_extract.v:33" 69 | wire input 2 \clk 70 | 71 | attribute \src "74_extract.v:35" 72 | wire width 32 output 4 \counter 73 | 74 | attribute \src "74_extract.v:34" 75 | wire width 33 input 3 \preset 76 | 77 | attribute \src "74_extract.v:32" 78 | wire input 1 \rst 79 | 80 | attribute \src "74_extract.v:41" 81 | cell $add $add$74_extract.v:41$9 82 | parameter \A_SIGNED 0 83 | parameter \A_WIDTH 32 84 | parameter \B_SIGNED 0 85 | parameter \B_WIDTH 1 86 | parameter \Y_WIDTH 32 87 | connect \A \counter 88 | connect \B 1'1 89 | connect \Y $add$74_extract.v:41$9_Y 90 | end 91 | 92 | attribute \src "74_extract.v:37" 93 | cell $dff $procdff$19 94 | parameter \CLK_POLARITY 1'1 95 | parameter \WIDTH 32 96 | connect \CLK \clk 97 | connect \D $0\counter[31:0] 98 | connect \Q \counter 99 | end 100 | 101 | attribute \full_case 1 102 | attribute \src "74_extract.v:38" 103 | cell $mux $procmux$11 104 | parameter \WIDTH 32 105 | connect \A \preset [31:0] 106 | connect \B $add$74_extract.v:41$9_Y 107 | connect \S \rst 108 | connect \Y $0\counter[31:0] 109 | end 110 | end 111 | 112 | attribute \cells_not_processed 1 113 | attribute \src "74_extract.v:1" 114 | module \_74xx_counter8 115 | 116 | attribute \src "74_extract.v:7" 117 | wire width 8 $0\counter[7:0] 118 | 119 | attribute \src "74_extract.v:11" 120 | wire width 8 $add$74_extract.v:11$3_Y 121 | 122 | attribute \src "74_extract.v:3" 123 | wire input 2 \clk 124 | 125 | attribute \src "74_extract.v:5" 126 | wire width 8 output 4 \counter 127 | 128 | attribute \src "74_extract.v:4" 129 | wire width 8 input 3 \preset 130 | 131 | attribute \src "74_extract.v:2" 132 | wire input 1 \rst 133 | 134 | attribute \src "74_extract.v:11" 135 | cell $add $add$74_extract.v:11$3 136 | parameter \A_SIGNED 0 137 | parameter \A_WIDTH 8 138 | parameter \B_SIGNED 0 139 | parameter \B_WIDTH 1 140 | parameter \Y_WIDTH 8 141 | connect \A \counter 142 | connect \B 1'1 143 | connect \Y $add$74_extract.v:11$3_Y 144 | end 145 | 146 | attribute \src "74_extract.v:7" 147 | cell $dff $procdff$21 148 | parameter \CLK_POLARITY 1'1 149 | parameter \WIDTH 8 150 | connect \CLK \clk 151 | connect \D $0\counter[7:0] 152 | connect \Q \counter 153 | end 154 | 155 | attribute \full_case 1 156 | attribute \src "74_extract.v:8" 157 | cell $mux $procmux$17 158 | parameter \WIDTH 8 159 | connect \A \preset 160 | connect \B $add$74_extract.v:11$3_Y 161 | connect \S \rst 162 | connect \Y $0\counter[7:0] 163 | end 164 | end 165 | -------------------------------------------------------------------------------- /74_extract.v: -------------------------------------------------------------------------------- 1 | module _74xx_counter8 ( 2 | input rst, 3 | input clk, 4 | input [7:0] preset, 5 | output reg [7:0] counter 6 | ); 7 | always @ (posedge clk) begin 8 | if (!rst) begin 9 | counter <= preset; 10 | end else begin 11 | counter <= counter + 1'b1; 12 | end 13 | end 14 | endmodule 15 | 16 | module _74xx_counter16 ( 17 | input rst, 18 | input clk, 19 | input [15:0] preset, 20 | output reg [15:0] counter 21 | ); 22 | always @ (posedge clk) begin 23 | if (!rst) begin 24 | counter <= preset; 25 | end else begin 26 | counter <= counter + 1'b1; 27 | end 28 | end 29 | endmodule 30 | 31 | module _74xx_counter32 ( 32 | input rst, 33 | input clk, 34 | input [32:0] preset, 35 | output reg [31:0] counter 36 | ); 37 | always @ (posedge clk) begin 38 | if (!rst) begin 39 | counter <= preset; 40 | end else begin 41 | counter <= counter + 1'b1; 42 | end 43 | end 44 | endmodule 45 | 46 | -------------------------------------------------------------------------------- /74_models.v: -------------------------------------------------------------------------------- 1 | module \74HC85_1x1CMP4 (A, B, Li, Ei, Gi, Lo, Eo, Go); 2 | 3 | input [3:0] A; 4 | input [3:0] B; 5 | input Li, Ei, Gi; 6 | output Lo, Eo, Go; 7 | 8 | assign Lo = (A < B) || (A == B && !Gi && !Ei); 9 | assign Go = (A > B) || (A == B && !Li && !Ei); 10 | assign Eo = (A == B) && Ei; 11 | 12 | endmodule 13 | 14 | module \74AC283_1x1ADD4 (A, B, CI, S, CO); 15 | 16 | input [3:0] A; 17 | input [3:0] B; 18 | input CI; 19 | output [3:0] S; 20 | output CO; 21 | 22 | assign {CO, S} = A + B + CI; 23 | 24 | endmodule 25 | 26 | module \74AC377_8x1DFFE (D, CE, CP, Q); 27 | 28 | input D, CE, CP; 29 | output reg Q; 30 | 31 | always @(posedge CP) begin 32 | if (!CE) Q <= D; 33 | end 34 | 35 | endmodule 36 | 37 | module \74HC688_1x1EQ8 (A, B, E, Q); 38 | 39 | input [7:0] A; 40 | input [7:0] B; 41 | input E; 42 | output Q; 43 | 44 | assign Q = E || !(A == B); 45 | 46 | endmodule 47 | 48 | module \74AC161_1x1COUNT4 (A, Q, RCO, ENT, CLK, LOAD); 49 | input [3:0] A; 50 | input CLK; 51 | input ENT; 52 | input LOAD; 53 | output reg [3:0] Q; 54 | output RCO; 55 | 56 | assign RCO = Q == 4'b1111; 57 | 58 | always @ (posedge CLK) begin 59 | if (!LOAD) begin 60 | Q <= A; 61 | end else if (ENT) begin 62 | Q <= Q + 1'b1; 63 | end 64 | end 65 | endmodule 66 | -------------------------------------------------------------------------------- /74_mux.v: -------------------------------------------------------------------------------- 1 | (* techmap_celltype = "$_MUX4_" *) 2 | module _80_74AC153_mux4 (A, B, C, D, S, T, Y); 3 | 4 | input A, B, C, D, S, T; 5 | output Y; 6 | 7 | \74AC153_2x1MUX4 _TECHMAP_REPLACE_ ( 8 | .A(A), 9 | .B(B), 10 | .C(C), 11 | .D(D), 12 | .S(S), 13 | .T(T), 14 | .Y(Y) 15 | ); 16 | 17 | endmodule 18 | 19 | (* techmap_celltype = "$_MUX8_" *) 20 | module _80_74AC151_mux8 (A, B, C, D, E, F, G, H, S, T, U, Y); 21 | 22 | input A, B, C, D, E, F, G, H, S, T, U; 23 | output Y; 24 | 25 | \74AC151_1x1MUX8 _TECHMAP_REPLACE_ ( 26 | .A(A), 27 | .B(B), 28 | .C(C), 29 | .D(D), 30 | .E(E), 31 | .F(F), 32 | .G(G), 33 | .H(H), 34 | .S(S), 35 | .T(T), 36 | .U(U), 37 | .Y(Y) 38 | ); 39 | 40 | endmodule 41 | -------------------------------------------------------------------------------- /74ac.lib: -------------------------------------------------------------------------------- 1 | library(74series) { 2 | technology("cmos"); 3 | 4 | time_unit: "1ns"; 5 | voltage_unit: "1V"; 6 | current_unit: "1mA"; 7 | capacitive_load_unit(1, pf); 8 | 9 | slew_lower_threshold_pct_fall: 30; 10 | slew_upper_threshold_pct_fall: 30; 11 | slew_lower_threshold_pct_rise: 70; 12 | slew_upper_threshold_pct_rise: 70; 13 | 14 | nom_process: 1; 15 | nom_temperature: 25; 16 | nom_voltage: 5; 17 | 18 | // 74AC00 quad 2-input NAND gate 19 | cell(74AC00_4x1NAND2) { 20 | area: 3; 21 | pin(A) { direction: input; } 22 | pin(B) { direction: input; } 23 | pin(Y) { direction: output; function: "(A*B)'"; } 24 | } 25 | 26 | // 74AC02 quad 2-input NOR gate 27 | cell(74AC02_4x1NOR2) { 28 | area: 3; 29 | pin(A) { direction: input; } 30 | pin(B) { direction: input; } 31 | pin(Y) { direction: output; function: "(A+B)'"; } 32 | } 33 | 34 | // 74AC04 hex inverter 35 | cell(74AC04_6x1NOT) { 36 | area: 2; 37 | pin(A) { 38 | direction: input; 39 | capacitance: 3.5; 40 | } 41 | pin(Y) { 42 | direction: output; 43 | capacitance: 0.0; 44 | max_capacitance: 29.0; 45 | function: "A'"; 46 | /* timing() { 47 | timing_type: "combinational"; 48 | timing_sense: "negative_unate"; 49 | related_pin: "A"; 50 | intrinsic_rise: 1.5; 51 | intrinsic_fall: 1.5; 52 | } */ 53 | } 54 | } 55 | 56 | // 74AC08 quad 2-input AND 57 | cell(74AC08_4x1AND2) { 58 | area: 3; 59 | pin(A) { direction: input; } 60 | pin(B) { direction: input; } 61 | pin(Y) { direction: output; function: "A*B"; } 62 | } 63 | 64 | // 74AC10 triple 3-input NAND 65 | cell(74AC10_3x1NAND3) { 66 | area: 4; 67 | pin(A) { direction: input; } 68 | pin(B) { direction: input; } 69 | pin(C) { direction: input; } 70 | pin(Y) { direction: output; function: "(A*B*C)'"; } 71 | } 72 | 73 | // 74AC20 dual 4-input NAND 74 | cell(74AC20_2x1NAND4) { 75 | area: 5; 76 | pin(A) { direction: input; } 77 | pin(B) { direction: input; } 78 | pin(C) { direction: input; } 79 | pin(D) { direction: input; } 80 | pin(Y) { direction: output; function: "(A*B*C*D)'"; } 81 | } 82 | 83 | // 74AC32 quad 2-input OR gate 84 | cell(74AC32_4x1OR2) { 85 | area: 3; 86 | pin(A) { direction: input; } 87 | pin(B) { direction: input; } 88 | pin(Y) { direction: output; function: "(A+B)"; } 89 | } 90 | 91 | // 74AC74 dual D flip-flop with set and reset 92 | cell(74AC74_2x1DFFSR) { 93 | area: 5; 94 | ff(IQ, IQN) { 95 | clocked_on: "CLK"; 96 | next_state: "D"; 97 | clear: "C'"; 98 | preset: "P'"; 99 | clear_preset_var1: H; 100 | clear_preset_var2: H; 101 | } 102 | pin(CLK) { direction: input; clock: true; } 103 | pin(C) { direction: input; } 104 | pin(P) { direction: input; } 105 | pin(D) { direction: input; } 106 | pin(Q) { direction: output; function: "IQ"; } 107 | } 108 | 109 | // 74AC273 octal D flip-flop with common reset 110 | cell(74AC273_8x1DFFR) { 111 | area: 2.25; // amortized clock and reset cost 112 | ff(IQ, IQN) { 113 | clocked_on: "CLK"; 114 | next_state: "D"; 115 | clear: "C'"; 116 | } 117 | pin(CLK) { direction: input; clock: true; } 118 | pin(C) { direction: input; } 119 | pin(D) { direction: input; } 120 | pin(Q) { direction: output; function: "IQ"; } 121 | } 122 | 123 | // 74AC86 quad 2-input XOR gate 124 | cell(74AC86_4x1XOR2) { 125 | area: 3; 126 | pin(A) { direction: input; } 127 | pin(B) { direction: input; } 128 | pin(Y) { direction: output; function: "(A*B')+(A'*B)"; } 129 | } 130 | 131 | // 74AC151 single 8:1 multiplexer 132 | cell(74AC151_1x1MUX8) { 133 | area: 12; 134 | pin(A) { direction: input; } 135 | pin(B) { direction: input; } 136 | pin(C) { direction: input; } 137 | pin(D) { direction: input; } 138 | pin(E) { direction: input; } 139 | pin(F) { direction: input; } 140 | pin(G) { direction: input; } 141 | pin(H) { direction: input; } 142 | pin(S) { direction: input; } 143 | pin(T) { direction: input; } 144 | pin(U) { direction: input; } 145 | pin(Y) { direction: output; 146 | function: "(S'*T'*U'*A)+(S*T'*U'*B)+(S'*T*U'*C)+(S*T*U'*D)+(S'*T'*U*E)+(S*T'*U*F)+(S'*T*U*G)+(S*T*U*H)"; } 147 | } 148 | 149 | // 74AC151 single 8:1 multiplexer, inverting output 150 | cell(74AC151_1x1MUXI8) { 151 | area: 12; 152 | pin(A) { direction: input; } 153 | pin(B) { direction: input; } 154 | pin(C) { direction: input; } 155 | pin(D) { direction: input; } 156 | pin(E) { direction: input; } 157 | pin(F) { direction: input; } 158 | pin(G) { direction: input; } 159 | pin(H) { direction: input; } 160 | pin(S) { direction: input; } 161 | pin(T) { direction: input; } 162 | pin(U) { direction: input; } 163 | pin(Y) { direction: output; 164 | function: "((S'*T'*U'*A)+(S*T'*U'*B)+(S'*T*U'*C)+(S*T*U'*D)+(S'*T'*U*E)+(S*T'*U*F)+(S'*T*U*G)+(S*T*U*H))'"; } 165 | } 166 | 167 | 168 | // 74AC153 dual 4:1 multiplexer 169 | cell(74AC153_2x1MUX4) { 170 | area: 7; 171 | pin(A) { direction: input; } 172 | pin(B) { direction: input; } 173 | pin(C) { direction: input; } 174 | pin(D) { direction: input; } 175 | pin(S) { direction: input; } 176 | pin(T) { direction: input; } 177 | pin(Y) { direction: output; function: "((S'*T'*A)+(S*T'*B)+(S'*T*C)+(S*T*D))"; } 178 | } 179 | 180 | // 74AC257 quad 2:1 multiplexer 181 | cell(74AC257_4x1MUX2) { 182 | area: 4; 183 | pin(A) { direction: input; } 184 | pin(B) { direction: input; } 185 | pin(S) { direction: input; } 186 | pin(Y) { direction: output; function: "(S'*A)+(S*B)"; } 187 | } 188 | 189 | // A buffer cell needed to make ABC happy 190 | // Will get optimized away 191 | cell("$_BUF_") { 192 | area: 2; 193 | pin(A) { direction: input; } 194 | pin(Y) { direction: output; function: "A"; } 195 | } 196 | 197 | // 74AC374 octal D flip-flop 198 | cell(74AC374_8x1DFF) { 199 | area: 2.0625; // amortized clock pin cost 200 | ff(IQ, IQN) { clocked_on: "CLK"; next_state: "D"; } 201 | pin(CLK) { direction: input; clock: true; } 202 | pin(D) { direction: input; } 203 | pin(Q) { direction: output; function: "IQ"; } 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /benchmarks/arlet_6502.v: -------------------------------------------------------------------------------- 1 | /* 2 | * verilog model of 6502 CPU. 3 | * 4 | * (C) Arlet Ottens, 5 | * 6 | * Feel free to use this code in any project (commercial or not), as long as you 7 | * keep this message, and the copyright notice. This code is provided "as is", 8 | * without any warranties of any kind. 9 | * 10 | */ 11 | 12 | /* 13 | * Note that not all 6502 interface signals are supported (yet). The goal 14 | * is to create an Acorn Atom model, and the Atom didn't use all signals on 15 | * the main board. 16 | * 17 | * The data bus is implemented as separate read/write buses. Combine them 18 | * on the output pads if external memory is required. 19 | */ 20 | 21 | `include "arlet_6502_alu.v" 22 | 23 | module cpu( clk, reset, AB, DI, DO, WE, IRQ, NMI, RDY ); 24 | 25 | input clk; // CPU clock 26 | input reset; // reset signal 27 | output reg [15:0] AB; // address bus 28 | input [7:0] DI; // data in, read bus 29 | output [7:0] DO; // data out, write bus 30 | output WE; // write enable 31 | input IRQ; // interrupt request 32 | input NMI; // non-maskable interrupt request 33 | input RDY; // Ready signal. Pauses CPU when RDY=0 34 | 35 | /* 36 | * internal signals 37 | */ 38 | 39 | reg [15:0] PC; // Program Counter 40 | reg [7:0] ABL; // Address Bus Register LSB 41 | reg [7:0] ABH; // Address Bus Register MSB 42 | wire [7:0] ADD; // Adder Hold Register (registered in ALU) 43 | 44 | reg [7:0] DIHOLD; // Hold for Data In 45 | reg DIHOLD_valid; // 46 | wire [7:0] DIMUX; // 47 | 48 | reg [7:0] IRHOLD; // Hold for Instruction register 49 | reg IRHOLD_valid; // Valid instruction in IRHOLD 50 | 51 | reg [7:0] AXYS[3:0]; // A, X, Y and S register file 52 | 53 | reg C = 0; // carry flag (init at zero to avoid X's in ALU sim) 54 | reg Z = 0; // zero flag 55 | reg I = 0; // interrupt flag 56 | reg D = 0; // decimal flag 57 | reg V = 0; // overflow flag 58 | reg N = 0; // negative flag 59 | wire AZ; // ALU Zero flag 60 | wire AV; // ALU overflow flag 61 | wire AN; // ALU negative flag 62 | wire HC; // ALU half carry 63 | 64 | reg [7:0] AI; // ALU Input A 65 | reg [7:0] BI; // ALU Input B 66 | wire [7:0] DI; // Data In 67 | wire [7:0] IR; // Instruction register 68 | reg [7:0] DO; // Data Out 69 | reg WE; // Write Enable 70 | reg CI; // Carry In 71 | wire CO; // Carry Out 72 | wire [7:0] PCH = PC[15:8]; 73 | wire [7:0] PCL = PC[7:0]; 74 | 75 | reg NMI_edge = 0; // captured NMI edge 76 | 77 | reg [1:0] regsel; // Select A, X, Y or S register 78 | wire [7:0] regfile = AXYS[regsel]; // Selected register output 79 | 80 | parameter 81 | SEL_A = 2'd0, 82 | SEL_S = 2'd1, 83 | SEL_X = 2'd2, 84 | SEL_Y = 2'd3; 85 | 86 | /* 87 | * define some signals for watching in simulator output 88 | */ 89 | 90 | 91 | `ifdef SIM 92 | wire [7:0] A = AXYS[SEL_A]; // Accumulator 93 | wire [7:0] X = AXYS[SEL_X]; // X register 94 | wire [7:0] Y = AXYS[SEL_Y]; // Y register 95 | wire [7:0] S = AXYS[SEL_S]; // Stack pointer 96 | `endif 97 | 98 | wire [7:0] P = { N, V, 2'b11, D, I, Z, C }; 99 | 100 | /* 101 | * instruction decoder/sequencer 102 | */ 103 | 104 | reg [5:0] state; 105 | 106 | /* 107 | * control signals 108 | */ 109 | 110 | reg PC_inc; // Increment PC 111 | reg [15:0] PC_temp; // intermediate value of PC 112 | 113 | reg [1:0] src_reg; // source register index 114 | reg [1:0] dst_reg; // destination register index 115 | 116 | reg index_y; // if set, then Y is index reg rather than X 117 | reg load_reg; // loading a register (A, X, Y, S) in this instruction 118 | reg inc; // increment 119 | reg write_back; // set if memory is read/modified/written 120 | reg load_only; // LDA/LDX/LDY instruction 121 | reg store; // doing store (STA/STX/STY) 122 | reg adc_sbc; // doing ADC/SBC 123 | reg compare; // doing CMP/CPY/CPX 124 | reg shift; // doing shift/rotate instruction 125 | reg rotate; // doing rotate (no shift) 126 | reg backwards; // backwards branch 127 | reg cond_true; // branch condition is true 128 | reg [2:0] cond_code; // condition code bits from instruction 129 | reg shift_right; // Instruction ALU shift/rotate right 130 | reg alu_shift_right; // Current cycle shift right enable 131 | reg [3:0] op; // Main ALU operation for instruction 132 | reg [3:0] alu_op; // Current cycle ALU operation 133 | reg adc_bcd; // ALU should do BCD style carry 134 | reg adj_bcd; // results should be BCD adjusted 135 | 136 | /* 137 | * some flip flops to remember we're doing special instructions. These 138 | * get loaded at the DECODE state, and used later 139 | */ 140 | reg bit_ins; // doing BIT instruction 141 | reg plp; // doing PLP instruction 142 | reg php; // doing PHP instruction 143 | reg clc; // clear carry 144 | reg sec; // set carry 145 | reg cld; // clear decimal 146 | reg sed; // set decimal 147 | reg cli; // clear interrupt 148 | reg sei; // set interrupt 149 | reg clv; // clear overflow 150 | reg brk; // doing BRK 151 | 152 | reg res; // in reset 153 | 154 | /* 155 | * ALU operations 156 | */ 157 | 158 | parameter 159 | OP_OR = 4'b1100, 160 | OP_AND = 4'b1101, 161 | OP_EOR = 4'b1110, 162 | OP_ADD = 4'b0011, 163 | OP_SUB = 4'b0111, 164 | OP_ROL = 4'b1011, 165 | OP_A = 4'b1111; 166 | 167 | /* 168 | * Microcode state machine. Basically, every addressing mode has its own 169 | * path through the state machine. Additional information, such as the 170 | * operation, source and destination registers are decoded in parallel, and 171 | * kept in separate flops. 172 | */ 173 | 174 | parameter 175 | ABS0 = 6'd0, // ABS - fetch LSB 176 | ABS1 = 6'd1, // ABS - fetch MSB 177 | ABSX0 = 6'd2, // ABS, X - fetch LSB and send to ALU (+X) 178 | ABSX1 = 6'd3, // ABS, X - fetch MSB and send to ALU (+Carry) 179 | ABSX2 = 6'd4, // ABS, X - Wait for ALU (only if needed) 180 | BRA0 = 6'd5, // Branch - fetch offset and send to ALU (+PC[7:0]) 181 | BRA1 = 6'd6, // Branch - fetch opcode, and send PC[15:8] to ALU 182 | BRA2 = 6'd7, // Branch - fetch opcode (if page boundary crossed) 183 | BRK0 = 6'd8, // BRK/IRQ - push PCH, send S to ALU (-1) 184 | BRK1 = 6'd9, // BRK/IRQ - push PCL, send S to ALU (-1) 185 | BRK2 = 6'd10, // BRK/IRQ - push P, send S to ALU (-1) 186 | BRK3 = 6'd11, // BRK/IRQ - write S, and fetch @ fffe 187 | DECODE = 6'd12, // IR is valid, decode instruction, and write prev reg 188 | FETCH = 6'd13, // fetch next opcode, and perform prev ALU op 189 | INDX0 = 6'd14, // (ZP,X) - fetch ZP address, and send to ALU (+X) 190 | INDX1 = 6'd15, // (ZP,X) - fetch LSB at ZP+X, calculate ZP+X+1 191 | INDX2 = 6'd16, // (ZP,X) - fetch MSB at ZP+X+1 192 | INDX3 = 6'd17, // (ZP,X) - fetch data 193 | INDY0 = 6'd18, // (ZP),Y - fetch ZP address, and send ZP to ALU (+1) 194 | INDY1 = 6'd19, // (ZP),Y - fetch at ZP+1, and send LSB to ALU (+Y) 195 | INDY2 = 6'd20, // (ZP),Y - fetch data, and send MSB to ALU (+Carry) 196 | INDY3 = 6'd21, // (ZP),Y) - fetch data (if page boundary crossed) 197 | JMP0 = 6'd22, // JMP - fetch PCL and hold 198 | JMP1 = 6'd23, // JMP - fetch PCH 199 | JMPI0 = 6'd24, // JMP IND - fetch LSB and send to ALU for delay (+0) 200 | JMPI1 = 6'd25, // JMP IND - fetch MSB, proceed with JMP0 state 201 | JSR0 = 6'd26, // JSR - push PCH, save LSB, send S to ALU (-1) 202 | JSR1 = 6'd27, // JSR - push PCL, send S to ALU (-1) 203 | JSR2 = 6'd28, // JSR - write S 204 | JSR3 = 6'd29, // JSR - fetch MSB 205 | PULL0 = 6'd30, // PLP/PLA - save next op in IRHOLD, send S to ALU (+1) 206 | PULL1 = 6'd31, // PLP/PLA - fetch data from stack, write S 207 | PULL2 = 6'd32, // PLP/PLA - prefetch op, but don't increment PC 208 | PUSH0 = 6'd33, // PHP/PHA - send A to ALU (+0) 209 | PUSH1 = 6'd34, // PHP/PHA - write A/P, send S to ALU (-1) 210 | READ = 6'd35, // Read memory for read/modify/write (INC, DEC, shift) 211 | REG = 6'd36, // Read register for reg-reg transfers 212 | RTI0 = 6'd37, // RTI - send S to ALU (+1) 213 | RTI1 = 6'd38, // RTI - read P from stack 214 | RTI2 = 6'd39, // RTI - read PCL from stack 215 | RTI3 = 6'd40, // RTI - read PCH from stack 216 | RTI4 = 6'd41, // RTI - read PCH from stack 217 | RTS0 = 6'd42, // RTS - send S to ALU (+1) 218 | RTS1 = 6'd43, // RTS - read PCL from stack 219 | RTS2 = 6'd44, // RTS - write PCL to ALU, read PCH 220 | RTS3 = 6'd45, // RTS - load PC and increment 221 | WRITE = 6'd46, // Write memory for read/modify/write 222 | ZP0 = 6'd47, // Z-page - fetch ZP address 223 | ZPX0 = 6'd48, // ZP, X - fetch ZP, and send to ALU (+X) 224 | ZPX1 = 6'd49; // ZP, X - load from memory 225 | 226 | `ifdef SIM 227 | 228 | /* 229 | * easy to read names in simulator output 230 | */ 231 | reg [8*6-1:0] statename; 232 | 233 | always @* 234 | case( state ) 235 | DECODE: statename = "DECODE"; 236 | REG: statename = "REG"; 237 | ZP0: statename = "ZP0"; 238 | ZPX0: statename = "ZPX0"; 239 | ZPX1: statename = "ZPX1"; 240 | ABS0: statename = "ABS0"; 241 | ABS1: statename = "ABS1"; 242 | ABSX0: statename = "ABSX0"; 243 | ABSX1: statename = "ABSX1"; 244 | ABSX2: statename = "ABSX2"; 245 | INDX0: statename = "INDX0"; 246 | INDX1: statename = "INDX1"; 247 | INDX2: statename = "INDX2"; 248 | INDX3: statename = "INDX3"; 249 | INDY0: statename = "INDY0"; 250 | INDY1: statename = "INDY1"; 251 | INDY2: statename = "INDY2"; 252 | INDY3: statename = "INDY3"; 253 | READ: statename = "READ"; 254 | WRITE: statename = "WRITE"; 255 | FETCH: statename = "FETCH"; 256 | PUSH0: statename = "PUSH0"; 257 | PUSH1: statename = "PUSH1"; 258 | PULL0: statename = "PULL0"; 259 | PULL1: statename = "PULL1"; 260 | PULL2: statename = "PULL2"; 261 | JSR0: statename = "JSR0"; 262 | JSR1: statename = "JSR1"; 263 | JSR2: statename = "JSR2"; 264 | JSR3: statename = "JSR3"; 265 | RTI0: statename = "RTI0"; 266 | RTI1: statename = "RTI1"; 267 | RTI2: statename = "RTI2"; 268 | RTI3: statename = "RTI3"; 269 | RTI4: statename = "RTI4"; 270 | RTS0: statename = "RTS0"; 271 | RTS1: statename = "RTS1"; 272 | RTS2: statename = "RTS2"; 273 | RTS3: statename = "RTS3"; 274 | BRK0: statename = "BRK0"; 275 | BRK1: statename = "BRK1"; 276 | BRK2: statename = "BRK2"; 277 | BRK3: statename = "BRK3"; 278 | BRA0: statename = "BRA0"; 279 | BRA1: statename = "BRA1"; 280 | BRA2: statename = "BRA2"; 281 | JMP0: statename = "JMP0"; 282 | JMP1: statename = "JMP1"; 283 | JMPI0: statename = "JMPI0"; 284 | JMPI1: statename = "JMPI1"; 285 | endcase 286 | 287 | //always @( PC ) 288 | // $display( "%t, PC:%04x IR:%02x A:%02x X:%02x Y:%02x S:%02x C:%d Z:%d V:%d N:%d P:%02x", $time, PC, IR, A, X, Y, S, C, Z, V, N, P ); 289 | 290 | `endif 291 | 292 | 293 | 294 | /* 295 | * Program Counter Increment/Load. First calculate the base value in 296 | * PC_temp. 297 | */ 298 | always @* 299 | case( state ) 300 | DECODE: if( (~I & IRQ) | NMI_edge ) 301 | PC_temp = { ABH, ABL }; 302 | else 303 | PC_temp = PC; 304 | 305 | 306 | JMP1, 307 | JMPI1, 308 | JSR3, 309 | RTS3, 310 | RTI4: PC_temp = { DIMUX, ADD }; 311 | 312 | BRA1: PC_temp = { ABH, ADD }; 313 | 314 | BRA2: PC_temp = { ADD, PCL }; 315 | 316 | BRK2: PC_temp = res ? 16'hfffc : 317 | NMI_edge ? 16'hfffa : 16'hfffe; 318 | 319 | default: PC_temp = PC; 320 | endcase 321 | 322 | /* 323 | * Determine wether we need PC_temp, or PC_temp + 1 324 | */ 325 | always @* 326 | case( state ) 327 | DECODE: if( (~I & IRQ) | NMI_edge ) 328 | PC_inc = 0; 329 | else 330 | PC_inc = 1; 331 | 332 | ABS0, 333 | ABSX0, 334 | FETCH, 335 | BRA0, 336 | BRA2, 337 | BRK3, 338 | JMPI1, 339 | JMP1, 340 | RTI4, 341 | RTS3: PC_inc = 1; 342 | 343 | BRA1: PC_inc = CO ^~ backwards; 344 | 345 | default: PC_inc = 0; 346 | endcase 347 | 348 | /* 349 | * Set new PC 350 | */ 351 | always @(posedge clk) 352 | if( RDY ) 353 | PC <= PC_temp + PC_inc; 354 | 355 | /* 356 | * Address Generator 357 | */ 358 | 359 | parameter 360 | ZEROPAGE = 8'h00, 361 | STACKPAGE = 8'h01; 362 | 363 | always @* 364 | case( state ) 365 | ABSX1, 366 | INDX3, 367 | INDY2, 368 | JMP1, 369 | JMPI1, 370 | RTI4, 371 | ABS1: AB = { DIMUX, ADD }; 372 | 373 | BRA2, 374 | INDY3, 375 | ABSX2: AB = { ADD, ABL }; 376 | 377 | BRA1: AB = { ABH, ADD }; 378 | 379 | JSR0, 380 | PUSH1, 381 | RTS0, 382 | RTI0, 383 | BRK0: AB = { STACKPAGE, regfile }; 384 | 385 | BRK1, 386 | JSR1, 387 | PULL1, 388 | RTS1, 389 | RTS2, 390 | RTI1, 391 | RTI2, 392 | RTI3, 393 | BRK2: AB = { STACKPAGE, ADD }; 394 | 395 | INDY1, 396 | INDX1, 397 | ZPX1, 398 | INDX2: AB = { ZEROPAGE, ADD }; 399 | 400 | ZP0, 401 | INDY0: AB = { ZEROPAGE, DIMUX }; 402 | 403 | REG, 404 | READ, 405 | WRITE: AB = { ABH, ABL }; 406 | 407 | default: AB = PC; 408 | endcase 409 | 410 | /* 411 | * ABH/ABL pair is used for registering previous address bus state. 412 | * This can be used to keep the current address, freeing up the original 413 | * source of the address, such as the ALU or DI. 414 | */ 415 | always @(posedge clk) 416 | if( state != PUSH0 && state != PUSH1 && RDY && 417 | state != PULL0 && state != PULL1 && state != PULL2 ) 418 | begin 419 | ABL <= AB[7:0]; 420 | ABH <= AB[15:8]; 421 | end 422 | 423 | /* 424 | * Data Out MUX 425 | */ 426 | always @* 427 | case( state ) 428 | WRITE: DO = ADD; 429 | 430 | JSR0, 431 | BRK0: DO = PCH; 432 | 433 | JSR1, 434 | BRK1: DO = PCL; 435 | 436 | PUSH1: DO = php ? P : ADD; 437 | 438 | BRK2: DO = (IRQ | NMI_edge) ? (P & 8'b1110_1111) : P; 439 | 440 | default: DO = regfile; 441 | endcase 442 | 443 | /* 444 | * Write Enable Generator 445 | */ 446 | 447 | always @* 448 | case( state ) 449 | BRK0, // writing to stack or memory 450 | BRK1, 451 | BRK2, 452 | JSR0, 453 | JSR1, 454 | PUSH1, 455 | WRITE: WE = 1; 456 | 457 | INDX3, // only if doing a STA, STX or STY 458 | INDY3, 459 | ABSX2, 460 | ABS1, 461 | ZPX1, 462 | ZP0: WE = store; 463 | 464 | default: WE = 0; 465 | endcase 466 | 467 | /* 468 | * register file, contains A, X, Y and S (stack pointer) registers. At each 469 | * cycle only 1 of those registers needs to be accessed, so they combined 470 | * in a small memory, saving resources. 471 | */ 472 | 473 | reg write_register; // set when register file is written 474 | 475 | always @* 476 | case( state ) 477 | DECODE: write_register = load_reg & ~plp; 478 | 479 | PULL1, 480 | RTS2, 481 | RTI3, 482 | BRK3, 483 | JSR0, 484 | JSR2 : write_register = 1; 485 | 486 | default: write_register = 0; 487 | endcase 488 | 489 | /* 490 | * BCD adjust logic 491 | */ 492 | 493 | always @(posedge clk) 494 | adj_bcd <= adc_sbc & D; // '1' when doing a BCD instruction 495 | 496 | reg [3:0] ADJL; 497 | reg [3:0] ADJH; 498 | 499 | // adjustment term to be added to ADD[3:0] based on the following 500 | // adj_bcd: '1' if doing ADC/SBC with D=1 501 | // adc_bcd: '1' if doing ADC with D=1 502 | // HC : half carry bit from ALU 503 | always @* begin 504 | casex( {adj_bcd, adc_bcd, HC} ) 505 | 3'b0xx: ADJL = 4'd0; // no BCD instruction 506 | 3'b100: ADJL = 4'd10; // SBC, and digital borrow 507 | 3'b101: ADJL = 4'd0; // SBC, but no borrow 508 | 3'b110: ADJL = 4'd0; // ADC, but no carry 509 | 3'b111: ADJL = 4'd6; // ADC, and decimal/digital carry 510 | endcase 511 | end 512 | 513 | // adjustment term to be added to ADD[7:4] based on the following 514 | // adj_bcd: '1' if doing ADC/SBC with D=1 515 | // adc_bcd: '1' if doing ADC with D=1 516 | // CO : carry out bit from ALU 517 | always @* begin 518 | casex( {adj_bcd, adc_bcd, CO} ) 519 | 3'b0xx: ADJH = 4'd0; // no BCD instruction 520 | 3'b100: ADJH = 4'd10; // SBC, and digital borrow 521 | 3'b101: ADJH = 4'd0; // SBC, but no borrow 522 | 3'b110: ADJH = 4'd0; // ADC, but no carry 523 | 3'b111: ADJH = 4'd6; // ADC, and decimal/digital carry 524 | endcase 525 | end 526 | 527 | /* 528 | * write to a register. Usually this is the (BCD corrected) output of the 529 | * ALU, but in case of the JSR0 we use the S register to temporarily store 530 | * the PCL. This is possible, because the S register itself is stored in 531 | * the ALU during those cycles. 532 | */ 533 | always @(posedge clk) 534 | if( write_register & RDY ) 535 | AXYS[regsel] <= (state == JSR0) ? DIMUX : { ADD[7:4] + ADJH, ADD[3:0] + ADJL }; 536 | 537 | /* 538 | * register select logic. This determines which of the A, X, Y or 539 | * S registers will be accessed. 540 | */ 541 | 542 | always @* 543 | case( state ) 544 | INDY1, 545 | INDX0, 546 | ZPX0, 547 | ABSX0 : regsel = index_y ? SEL_Y : SEL_X; 548 | 549 | 550 | DECODE : regsel = dst_reg; 551 | 552 | BRK0, 553 | BRK3, 554 | JSR0, 555 | JSR2, 556 | PULL0, 557 | PULL1, 558 | PUSH1, 559 | RTI0, 560 | RTI3, 561 | RTS0, 562 | RTS2 : regsel = SEL_S; 563 | 564 | default: regsel = src_reg; 565 | endcase 566 | 567 | /* 568 | * ALU 569 | */ 570 | 571 | ALU ALU( .clk(clk), 572 | .op(alu_op), 573 | .right(alu_shift_right), 574 | .AI(AI), 575 | .BI(BI), 576 | .CI(CI), 577 | .BCD(adc_bcd & (state == FETCH)), 578 | .CO(CO), 579 | .OUT(ADD), 580 | .V(AV), 581 | .Z(AZ), 582 | .N(AN), 583 | .HC(HC), 584 | .RDY(RDY) ); 585 | 586 | /* 587 | * Select current ALU operation 588 | */ 589 | 590 | always @* 591 | case( state ) 592 | READ: alu_op = op; 593 | 594 | BRA1: alu_op = backwards ? OP_SUB : OP_ADD; 595 | 596 | FETCH, 597 | REG : alu_op = op; 598 | 599 | DECODE, 600 | ABS1: alu_op = 1'bx; 601 | 602 | PUSH1, 603 | BRK0, 604 | BRK1, 605 | BRK2, 606 | JSR0, 607 | JSR1: alu_op = OP_SUB; 608 | 609 | default: alu_op = OP_ADD; 610 | endcase 611 | 612 | /* 613 | * Determine shift right signal to ALU 614 | */ 615 | 616 | always @* 617 | if( state == FETCH || state == REG || state == READ ) 618 | alu_shift_right = shift_right; 619 | else 620 | alu_shift_right = 0; 621 | 622 | /* 623 | * Sign extend branch offset. 624 | */ 625 | 626 | always @(posedge clk) 627 | if( RDY ) 628 | backwards <= DIMUX[7]; 629 | 630 | /* 631 | * ALU A Input MUX 632 | */ 633 | 634 | always @* 635 | case( state ) 636 | JSR1, 637 | RTS1, 638 | RTI1, 639 | RTI2, 640 | BRK1, 641 | BRK2, 642 | INDX1: AI = ADD; 643 | 644 | REG, 645 | ZPX0, 646 | INDX0, 647 | ABSX0, 648 | RTI0, 649 | RTS0, 650 | JSR0, 651 | JSR2, 652 | BRK0, 653 | PULL0, 654 | INDY1, 655 | PUSH0, 656 | PUSH1: AI = regfile; 657 | 658 | BRA0, 659 | READ: AI = DIMUX; 660 | 661 | BRA1: AI = ABH; // don't use PCH in case we're 662 | 663 | FETCH: AI = load_only ? 0 : regfile; 664 | 665 | DECODE, 666 | ABS1: AI = 8'hxx; // don't care 667 | 668 | default: AI = 0; 669 | endcase 670 | 671 | 672 | /* 673 | * ALU B Input mux 674 | */ 675 | 676 | always @* 677 | case( state ) 678 | BRA1, 679 | RTS1, 680 | RTI0, 681 | RTI1, 682 | RTI2, 683 | INDX1, 684 | READ, 685 | REG, 686 | JSR0, 687 | JSR1, 688 | JSR2, 689 | BRK0, 690 | BRK1, 691 | BRK2, 692 | PUSH0, 693 | PUSH1, 694 | PULL0, 695 | RTS0: BI = 8'h00; 696 | 697 | BRA0: BI = PCL; 698 | 699 | DECODE, 700 | ABS1: BI = 8'hxx; 701 | 702 | default: BI = DIMUX; 703 | endcase 704 | 705 | /* 706 | * ALU CI (carry in) mux 707 | */ 708 | 709 | always @* 710 | case( state ) 711 | INDY2, 712 | BRA1, 713 | ABSX1: CI = CO; 714 | 715 | DECODE, 716 | ABS1: CI = 1'bx; 717 | 718 | READ, 719 | REG: CI = rotate ? C : 720 | shift ? 0 : inc; 721 | 722 | FETCH: CI = rotate ? C : 723 | compare ? 1 : 724 | (shift | load_only) ? 0 : C; 725 | 726 | PULL0, 727 | RTI0, 728 | RTI1, 729 | RTI2, 730 | RTS0, 731 | RTS1, 732 | INDY0, 733 | INDX1: CI = 1; 734 | 735 | default: CI = 0; 736 | endcase 737 | 738 | /* 739 | * Processor Status Register update 740 | * 741 | */ 742 | 743 | /* 744 | * Update C flag when doing ADC/SBC, shift/rotate, compare 745 | */ 746 | always @(posedge clk ) 747 | if( shift && state == WRITE ) 748 | C <= CO; 749 | else if( state == RTI2 ) 750 | C <= DIMUX[0]; 751 | else if( ~write_back && state == DECODE ) begin 752 | if( adc_sbc | shift | compare ) 753 | C <= CO; 754 | else if( plp ) 755 | C <= ADD[0]; 756 | else begin 757 | if( sec ) C <= 1; 758 | if( clc ) C <= 0; 759 | end 760 | end 761 | 762 | /* 763 | * Update Z, N flags when writing A, X, Y, Memory, or when doing compare 764 | */ 765 | 766 | always @(posedge clk) 767 | if( state == WRITE ) 768 | Z <= AZ; 769 | else if( state == RTI2 ) 770 | Z <= DIMUX[1]; 771 | else if( state == DECODE ) begin 772 | if( plp ) 773 | Z <= ADD[1]; 774 | else if( (load_reg & (regsel != SEL_S)) | compare | bit_ins ) 775 | Z <= AZ; 776 | end 777 | 778 | always @(posedge clk) 779 | if( state == WRITE ) 780 | N <= AN; 781 | else if( state == RTI2 ) 782 | N <= DIMUX[7]; 783 | else if( state == DECODE ) begin 784 | if( plp ) 785 | N <= ADD[7]; 786 | else if( (load_reg & (regsel != SEL_S)) | compare ) 787 | N <= AN; 788 | end else if( state == FETCH && bit_ins ) 789 | N <= DIMUX[7]; 790 | 791 | /* 792 | * Update I flag 793 | */ 794 | 795 | always @(posedge clk) 796 | if( state == BRK3 ) 797 | I <= 1; 798 | else if( state == RTI2 ) 799 | I <= DIMUX[2]; 800 | else if( state == REG ) begin 801 | if( sei ) I <= 1; 802 | if( cli ) I <= 0; 803 | end else if( state == DECODE ) 804 | if( plp ) I <= ADD[2]; 805 | 806 | /* 807 | * Update D flag 808 | */ 809 | always @(posedge clk ) 810 | if( state == RTI2 ) 811 | D <= DIMUX[3]; 812 | else if( state == DECODE ) begin 813 | if( sed ) D <= 1; 814 | if( cld ) D <= 0; 815 | if( plp ) D <= ADD[3]; 816 | end 817 | 818 | /* 819 | * Update V flag 820 | */ 821 | always @(posedge clk ) 822 | if( state == RTI2 ) 823 | V <= DIMUX[6]; 824 | else if( state == DECODE ) begin 825 | if( adc_sbc ) V <= AV; 826 | if( clv ) V <= 0; 827 | if( plp ) V <= ADD[6]; 828 | end else if( state == FETCH && bit_ins ) 829 | V <= DIMUX[6]; 830 | 831 | /* 832 | * Instruction decoder 833 | */ 834 | 835 | /* 836 | * IR register/mux. Hold previous DI value in IRHOLD in PULL0 and PUSH0 837 | * states. In these states, the IR has been prefetched, and there is no 838 | * time to read the IR again before the next decode. 839 | */ 840 | 841 | always @(posedge clk ) 842 | if( reset ) 843 | IRHOLD_valid <= 0; 844 | else if( RDY ) begin 845 | if( state == PULL0 || state == PUSH0 ) begin 846 | IRHOLD <= DIMUX; 847 | IRHOLD_valid <= 1; 848 | end else if( state == DECODE ) 849 | IRHOLD_valid <= 0; 850 | end 851 | 852 | assign IR = (IRQ & ~I) | NMI_edge ? 8'h00 : 853 | IRHOLD_valid ? IRHOLD : DIMUX; 854 | 855 | always @(posedge clk ) 856 | if( RDY ) 857 | DIHOLD <= DI; 858 | 859 | assign DIMUX = ~RDY ? DIHOLD : DI; 860 | 861 | /* 862 | * Microcode state machine 863 | */ 864 | always @(posedge clk or posedge reset) 865 | if( reset ) 866 | state <= BRK0; 867 | else if( RDY ) case( state ) 868 | DECODE : 869 | casex ( IR ) 870 | 8'b0000_0000: state <= BRK0; 871 | 8'b0010_0000: state <= JSR0; 872 | 8'b0010_1100: state <= ABS0; // BIT abs 873 | 8'b0100_0000: state <= RTI0; // 874 | 8'b0100_1100: state <= JMP0; 875 | 8'b0110_0000: state <= RTS0; 876 | 8'b0110_1100: state <= JMPI0; 877 | 8'b0x00_1000: state <= PUSH0; 878 | 8'b0x10_1000: state <= PULL0; 879 | 8'b0xx1_1000: state <= REG; // CLC, SEC, CLI, SEI 880 | 8'b1xx0_00x0: state <= FETCH; // IMM 881 | 8'b1xx0_1100: state <= ABS0; // X/Y abs 882 | 8'b1xxx_1000: state <= REG; // DEY, TYA, ... 883 | 8'bxxx0_0001: state <= INDX0; 884 | 8'bxxx0_01xx: state <= ZP0; 885 | 8'bxxx0_1001: state <= FETCH; // IMM 886 | 8'bxxx0_1101: state <= ABS0; // even E column 887 | 8'bxxx0_1110: state <= ABS0; // even E column 888 | 8'bxxx1_0000: state <= BRA0; // odd 0 column 889 | 8'bxxx1_0001: state <= INDY0; // odd 1 column 890 | 8'bxxx1_01xx: state <= ZPX0; // odd 4,5,6,7 columns 891 | 8'bxxx1_1001: state <= ABSX0; // odd 9 column 892 | 8'bxxx1_11xx: state <= ABSX0; // odd C, D, E, F columns 893 | 8'bxxxx_1010: state <= REG; // A, TXA, ... NOP 894 | endcase 895 | 896 | ZP0 : state <= write_back ? READ : FETCH; 897 | 898 | ZPX0 : state <= ZPX1; 899 | ZPX1 : state <= write_back ? READ : FETCH; 900 | 901 | ABS0 : state <= ABS1; 902 | ABS1 : state <= write_back ? READ : FETCH; 903 | 904 | ABSX0 : state <= ABSX1; 905 | ABSX1 : state <= (CO | store | write_back) ? ABSX2 : FETCH; 906 | ABSX2 : state <= write_back ? READ : FETCH; 907 | 908 | INDX0 : state <= INDX1; 909 | INDX1 : state <= INDX2; 910 | INDX2 : state <= INDX3; 911 | INDX3 : state <= FETCH; 912 | 913 | INDY0 : state <= INDY1; 914 | INDY1 : state <= INDY2; 915 | INDY2 : state <= (CO | store) ? INDY3 : FETCH; 916 | INDY3 : state <= FETCH; 917 | 918 | READ : state <= WRITE; 919 | WRITE : state <= FETCH; 920 | FETCH : state <= DECODE; 921 | 922 | REG : state <= DECODE; 923 | 924 | PUSH0 : state <= PUSH1; 925 | PUSH1 : state <= DECODE; 926 | 927 | PULL0 : state <= PULL1; 928 | PULL1 : state <= PULL2; 929 | PULL2 : state <= DECODE; 930 | 931 | JSR0 : state <= JSR1; 932 | JSR1 : state <= JSR2; 933 | JSR2 : state <= JSR3; 934 | JSR3 : state <= FETCH; 935 | 936 | RTI0 : state <= RTI1; 937 | RTI1 : state <= RTI2; 938 | RTI2 : state <= RTI3; 939 | RTI3 : state <= RTI4; 940 | RTI4 : state <= DECODE; 941 | 942 | RTS0 : state <= RTS1; 943 | RTS1 : state <= RTS2; 944 | RTS2 : state <= RTS3; 945 | RTS3 : state <= FETCH; 946 | 947 | BRA0 : state <= cond_true ? BRA1 : DECODE; 948 | BRA1 : state <= (CO ^ backwards) ? BRA2 : DECODE; 949 | BRA2 : state <= DECODE; 950 | 951 | JMP0 : state <= JMP1; 952 | JMP1 : state <= DECODE; 953 | 954 | JMPI0 : state <= JMPI1; 955 | JMPI1 : state <= JMP0; 956 | 957 | BRK0 : state <= BRK1; 958 | BRK1 : state <= BRK2; 959 | BRK2 : state <= BRK3; 960 | BRK3 : state <= JMP0; 961 | 962 | endcase 963 | 964 | /* 965 | * Additional control signals 966 | */ 967 | 968 | always @(posedge clk) 969 | if( reset ) 970 | res <= 1; 971 | else if( state == DECODE ) 972 | res <= 0; 973 | 974 | always @(posedge clk) 975 | if( state == DECODE && RDY ) 976 | casex( IR ) 977 | 8'b0xx01010, // ASLA, ROLA, LSRA, RORA 978 | 8'b0xxxxx01, // ORA, AND, EOR, ADC 979 | 8'b100x10x0, // DEY, TYA, TXA, TXS 980 | 8'b1010xxx0, // LDA/LDX/LDY 981 | 8'b10111010, // TSX 982 | 8'b1011x1x0, // LDX/LDY 983 | 8'b11001010, // DEX 984 | 8'b1x1xxx01, // LDA, SBC 985 | 8'bxxx01000: // DEY, TAY, INY, INX 986 | load_reg <= 1; 987 | 988 | default: load_reg <= 0; 989 | endcase 990 | 991 | always @(posedge clk) 992 | if( state == DECODE && RDY ) 993 | casex( IR ) 994 | 8'b1110_1000, // INX 995 | 8'b1100_1010, // DEX 996 | 8'b101x_xx10: // LDX, TAX, TSX 997 | dst_reg <= SEL_X; 998 | 999 | 8'b0x00_1000, // PHP, PHA 1000 | 8'b1001_1010: // TXS 1001 | dst_reg <= SEL_S; 1002 | 1003 | 8'b1x00_1000, // DEY, DEX 1004 | 8'b101x_x100, // LDY 1005 | 8'b1010_x000: // LDY #imm, TAY 1006 | dst_reg <= SEL_Y; 1007 | 1008 | default: dst_reg <= SEL_A; 1009 | endcase 1010 | 1011 | always @(posedge clk) 1012 | if( state == DECODE && RDY ) 1013 | casex( IR ) 1014 | 8'b1011_1010: // TSX 1015 | src_reg <= SEL_S; 1016 | 1017 | 8'b100x_x110, // STX 1018 | 8'b100x_1x10, // TXA, TXS 1019 | 8'b1110_xx00, // INX, CPX 1020 | 8'b1100_1010: // DEX 1021 | src_reg <= SEL_X; 1022 | 1023 | 8'b100x_x100, // STY 1024 | 8'b1001_1000, // TYA 1025 | 8'b1100_xx00, // CPY 1026 | 8'b1x00_1000: // DEY, INY 1027 | src_reg <= SEL_Y; 1028 | 1029 | default: src_reg <= SEL_A; 1030 | endcase 1031 | 1032 | always @(posedge clk) 1033 | if( state == DECODE && RDY ) 1034 | casex( IR ) 1035 | 8'bxxx1_0001, // INDY 1036 | 8'b10x1_x110, // LDX/STX zpg/abs, Y 1037 | 8'bxxxx_1001: // abs, Y 1038 | index_y <= 1; 1039 | 1040 | default: index_y <= 0; 1041 | endcase 1042 | 1043 | 1044 | always @(posedge clk) 1045 | if( state == DECODE && RDY ) 1046 | casex( IR ) 1047 | 8'b100x_x1x0, // STX, STY 1048 | 8'b100x_xx01: // STA 1049 | store <= 1; 1050 | 1051 | default: store <= 0; 1052 | 1053 | endcase 1054 | 1055 | always @(posedge clk ) 1056 | if( state == DECODE && RDY ) 1057 | casex( IR ) 1058 | 8'b0xxx_x110, // ASL, ROL, LSR, ROR 1059 | 8'b11xx_x110: // DEC/INC 1060 | write_back <= 1; 1061 | 1062 | default: write_back <= 0; 1063 | endcase 1064 | 1065 | 1066 | always @(posedge clk ) 1067 | if( state == DECODE && RDY ) 1068 | casex( IR ) 1069 | 8'b101x_xxxx: // LDA, LDX, LDY 1070 | load_only <= 1; 1071 | default: load_only <= 0; 1072 | endcase 1073 | 1074 | always @(posedge clk ) 1075 | if( state == DECODE && RDY ) 1076 | casex( IR ) 1077 | 8'b111x_x110, // INC 1078 | 8'b11x0_1000: // INX, INY 1079 | inc <= 1; 1080 | 1081 | default: inc <= 0; 1082 | endcase 1083 | 1084 | always @(posedge clk ) 1085 | if( (state == DECODE || state == BRK0) && RDY ) 1086 | casex( IR ) 1087 | 8'bx11x_xx01: // SBC, ADC 1088 | adc_sbc <= 1; 1089 | 1090 | default: adc_sbc <= 0; 1091 | endcase 1092 | 1093 | always @(posedge clk ) 1094 | if( (state == DECODE || state == BRK0) && RDY ) 1095 | casex( IR ) 1096 | 8'b011x_xx01: // ADC 1097 | adc_bcd <= D; 1098 | 1099 | default: adc_bcd <= 0; 1100 | endcase 1101 | 1102 | always @(posedge clk ) 1103 | if( state == DECODE && RDY ) 1104 | casex( IR ) 1105 | 8'b0xxx_x110, // ASL, ROL, LSR, ROR (abs, absx, zpg, zpgx) 1106 | 8'b0xxx_1010: // ASL, ROL, LSR, ROR (acc) 1107 | shift <= 1; 1108 | 1109 | default: shift <= 0; 1110 | endcase 1111 | 1112 | always @(posedge clk ) 1113 | if( state == DECODE && RDY ) 1114 | casex( IR ) 1115 | 8'b11x0_0x00, // CPX, CPY (imm/zp) 1116 | 8'b11x0_1100, // CPX, CPY (abs) 1117 | 8'b110x_xx01: // CMP 1118 | compare <= 1; 1119 | 1120 | default: compare <= 0; 1121 | endcase 1122 | 1123 | always @(posedge clk ) 1124 | if( state == DECODE && RDY ) 1125 | casex( IR ) 1126 | 8'b01xx_xx10: // ROR, LSR 1127 | shift_right <= 1; 1128 | 1129 | default: shift_right <= 0; 1130 | endcase 1131 | 1132 | always @(posedge clk ) 1133 | if( state == DECODE && RDY ) 1134 | casex( IR ) 1135 | 8'b0x1x_1010, // ROL A, ROR A 1136 | 8'b0x1x_x110: // ROR, ROL 1137 | rotate <= 1; 1138 | 1139 | default: rotate <= 0; 1140 | endcase 1141 | 1142 | always @(posedge clk ) 1143 | if( state == DECODE && RDY ) 1144 | casex( IR ) 1145 | 8'b00xx_xx10: // ROL, ASL 1146 | op <= OP_ROL; 1147 | 1148 | 8'b0010_x100: // BIT zp/abs 1149 | op <= OP_AND; 1150 | 1151 | 8'b01xx_xx10: // ROR, LSR 1152 | op <= OP_A; 1153 | 1154 | 8'b1000_1000, // DEY 1155 | 8'b1100_1010, // DEX 1156 | 8'b110x_x110, // DEC 1157 | 8'b11xx_xx01, // CMP, SBC 1158 | 8'b11x0_0x00, // CPX, CPY (imm, zpg) 1159 | 8'b11x0_1100: op <= OP_SUB; 1160 | 1161 | 8'b010x_xx01, // EOR 1162 | 8'b00xx_xx01: // ORA, AND 1163 | op <= { 2'b11, IR[6:5] }; 1164 | 1165 | default: op <= OP_ADD; 1166 | endcase 1167 | 1168 | always @(posedge clk ) 1169 | if( state == DECODE && RDY ) 1170 | casex( IR ) 1171 | 8'b0010_x100: // BIT zp/abs 1172 | bit_ins <= 1; 1173 | 1174 | default: bit_ins <= 0; 1175 | endcase 1176 | 1177 | /* 1178 | * special instructions 1179 | */ 1180 | always @(posedge clk ) 1181 | if( state == DECODE && RDY ) begin 1182 | php <= (IR == 8'h08); 1183 | clc <= (IR == 8'h18); 1184 | plp <= (IR == 8'h28); 1185 | sec <= (IR == 8'h38); 1186 | cli <= (IR == 8'h58); 1187 | sei <= (IR == 8'h78); 1188 | clv <= (IR == 8'hb8); 1189 | cld <= (IR == 8'hd8); 1190 | sed <= (IR == 8'hf8); 1191 | brk <= (IR == 8'h00); 1192 | end 1193 | 1194 | always @(posedge clk) 1195 | if( RDY ) 1196 | cond_code <= IR[7:5]; 1197 | 1198 | always @* 1199 | case( cond_code ) 1200 | 3'b000: cond_true = ~N; 1201 | 3'b001: cond_true = N; 1202 | 3'b010: cond_true = ~V; 1203 | 3'b011: cond_true = V; 1204 | 3'b100: cond_true = ~C; 1205 | 3'b101: cond_true = C; 1206 | 3'b110: cond_true = ~Z; 1207 | 3'b111: cond_true = Z; 1208 | endcase 1209 | 1210 | 1211 | reg NMI_1 = 0; // delayed NMI signal 1212 | 1213 | always @(posedge clk) 1214 | NMI_1 <= NMI; 1215 | 1216 | always @(posedge clk ) 1217 | if( NMI_edge && state == BRK3 ) 1218 | NMI_edge <= 0; 1219 | else if( NMI & ~NMI_1 ) 1220 | NMI_edge <= 1; 1221 | 1222 | endmodule 1223 | -------------------------------------------------------------------------------- /benchmarks/arlet_6502_alu.v: -------------------------------------------------------------------------------- 1 | /* 2 | * ALU. 3 | * 4 | * AI and BI are 8 bit inputs. Result in OUT. 5 | * CI is Carry In. 6 | * CO is Carry Out. 7 | * 8 | * op[3:0] is defined as follows: 9 | * 10 | * 0011 AI + BI 11 | * 0111 AI - BI 12 | * 1011 AI + AI 13 | * 1100 AI | BI 14 | * 1101 AI & BI 15 | * 1110 AI ^ BI 16 | * 1111 AI 17 | * 18 | */ 19 | 20 | module ALU( clk, op, right, AI, BI, CI, CO, BCD, OUT, V, Z, N, HC, RDY ); 21 | input clk; 22 | input right; 23 | input [3:0] op; // operation 24 | input [7:0] AI; 25 | input [7:0] BI; 26 | input CI; 27 | input BCD; // BCD style carry 28 | output [7:0] OUT; 29 | output CO; 30 | output V; 31 | output Z; 32 | output N; 33 | output HC; 34 | input RDY; 35 | 36 | reg [7:0] OUT; 37 | reg CO; 38 | wire V; 39 | wire Z; 40 | reg N; 41 | reg HC; 42 | 43 | reg AI7; 44 | reg BI7; 45 | reg [8:0] temp_logic; 46 | reg [7:0] temp_BI; 47 | reg [4:0] temp_l; 48 | reg [4:0] temp_h; 49 | wire [8:0] temp = { temp_h, temp_l[3:0] }; 50 | wire adder_CI = (right | (op[3:2] == 2'b11)) ? 0 : CI; 51 | 52 | // calculate the logic operations. The 'case' can be done in 1 LUT per 53 | // bit. The 'right' shift is a simple mux that can be implemented by 54 | // F5MUX. 55 | always @* begin 56 | case( op[1:0] ) 57 | 2'b00: temp_logic = AI | BI; 58 | 2'b01: temp_logic = AI & BI; 59 | 2'b10: temp_logic = AI ^ BI; 60 | 2'b11: temp_logic = AI; 61 | endcase 62 | 63 | if( right ) 64 | temp_logic = { AI[0], CI, AI[7:1] }; 65 | end 66 | 67 | // Add logic result to BI input. This only makes sense when logic = AI. 68 | // This stage can be done in 1 LUT per bit, using carry chain logic. 69 | always @* begin 70 | case( op[3:2] ) 71 | 2'b00: temp_BI = BI; // A+B 72 | 2'b01: temp_BI = ~BI; // A-B 73 | 2'b10: temp_BI = temp_logic; // A+A 74 | 2'b11: temp_BI = 0; // A+0 75 | endcase 76 | end 77 | 78 | // HC9 is the half carry bit when doing BCD add 79 | wire HC9 = BCD & (temp_l[3:1] >= 3'd5); 80 | 81 | // CO9 is the carry-out bit when doing BCD add 82 | wire CO9 = BCD & (temp_h[3:1] >= 3'd5); 83 | 84 | // combined half carry bit 85 | wire temp_HC = temp_l[4] | HC9; 86 | 87 | // perform the addition as 2 separate nibble, so we get 88 | // access to the half carry flag 89 | always @* begin 90 | temp_l = temp_logic[3:0] + temp_BI[3:0] + adder_CI; 91 | temp_h = temp_logic[8:4] + temp_BI[7:4] + temp_HC; 92 | end 93 | 94 | // calculate the flags 95 | always @(posedge clk) 96 | if( RDY ) begin 97 | AI7 <= AI[7]; 98 | BI7 <= temp_BI[7]; 99 | OUT <= temp[7:0]; 100 | CO <= temp[8] | CO9; 101 | N <= temp[7]; 102 | HC <= temp_HC; 103 | end 104 | 105 | assign V = AI7 ^ BI7 ^ CO ^ N; 106 | assign Z = ~|OUT; 107 | 108 | endmodule 109 | -------------------------------------------------------------------------------- /benchmarks/cic5.v: -------------------------------------------------------------------------------- 1 | // 5th order CIC filter with decimation factor of 5 2 | // Author: Niels A. Moseley 3 | // Symbiotic EDA / Moseley Instruments 4 | // 12-11-2018 5 | 6 | module cic5( 7 | input clk, 8 | input rst_n, 9 | input signed [15:0] d_in, 10 | output reg signed [27:0] d_out, 11 | output reg d_out_valid 12 | ); 13 | 14 | reg signed [27:0] int_s [1:5]; // integrator states 15 | reg signed [27:0] comb_s [1:5]; // comb filter states 16 | reg signed [27:0] tmp [1:5]; // temporary var 17 | reg [2:0] decimation_count; 18 | 19 | integer i; 20 | 21 | always @(posedge clk) 22 | begin 23 | if (rst_n == 1'b0) 24 | begin 25 | for (i=1; i<=5; i=i+1) begin 26 | int_s[i] <= 16'd0; 27 | comb_s[i] <= 28'd0; 28 | end 29 | decimation_count <= 0; 30 | d_out_valid <= 0; 31 | d_out <= 0; 32 | end 33 | else 34 | begin 35 | // default updates 36 | d_out_valid <= 1'b0; 37 | decimation_count <= decimation_count + 1; 38 | 39 | // update the integrator filter states 40 | int_s[1] <= int_s[1] + d_in; 41 | for (i=2; i<=5; i=i+1) begin 42 | int_s[i] <= int_s[i] + int_s[i-1]; 43 | end 44 | 45 | // check if we can output new data 46 | // at the decimated rate 47 | 48 | if (decimation_count == 3'd4) 49 | begin 50 | // update the comb filter states 51 | tmp[1] = int_s[5] - comb_s[1]; 52 | comb_s[1] <= int_s[5]; 53 | for (i=2; i<=5; i=i+1) begin 54 | tmp[i] = tmp[i-1] - comb_s[i]; 55 | comb_s[i] <= tmp[i-1]; 56 | end 57 | 58 | decimation_count <= 0; 59 | d_out_valid <= 1'b1; 60 | d_out <= tmp[5]; 61 | end; 62 | end; 63 | end 64 | 65 | endmodule -------------------------------------------------------------------------------- /benchmarks/cic5_tb.v: -------------------------------------------------------------------------------- 1 | // Testbench for 5th order CIC filter with decimation factor of 5 2 | // Author: Niels A. Moseley 3 | // Symbiotic EDA / Moseley Instruments 4 | // 5 | // 12-11-2018 6 | 7 | 8 | module tb; 9 | 10 | reg clk = 0; 11 | reg rst_n = 0; 12 | reg signed [15:0] d_in = 0; 13 | wire signed [27:0] d_out = 0; 14 | wire d_out_valid; 15 | 16 | // clock generation 17 | always #1 clk=~clk; 18 | 19 | // devices under test 20 | cic5 dut(clk, rst_n, d_in, d_out, d_out_valid); 21 | 22 | initial 23 | begin 24 | $dumpfile("cic5.vcd"); 25 | $dumpvars; 26 | d_in <= 16'h7fff; 27 | #4 rst_n = 1'b1; 28 | #60 d_in <= -16'h7fff; 29 | #60 $finish; 30 | end 31 | 32 | endmodule 33 | -------------------------------------------------------------------------------- /benchmarks/cordic_10_16.v: -------------------------------------------------------------------------------- 1 | // pipelined CORDIC algorithm to calculate sin/cos pair from a given angle (0..1) 2 | // Author: Niels A. Moseley 3 | // 4 | 5 | 6 | // one stage of the cordic iteration with registered outputs 7 | module cordic_stage_16(clk, rst_n, x_in, y_in, angle_in, angle_adj, x_out, y_out, angle_out); 8 | parameter SHIFT = 1; 9 | 10 | // inputs 11 | input clk; 12 | input rst_n; 13 | input signed [16-1:0] x_in; 14 | input signed [16-1:0] y_in; 15 | input signed [16-1:0] angle_in; 16 | input signed [16-1:0] angle_adj; 17 | 18 | // outputs 19 | output reg signed [16-1:0] x_out; 20 | output reg signed [16-1:0] y_out; 21 | output reg signed [16-1:0] angle_out; 22 | 23 | // internal signal 24 | reg signed [16-1:0] new_x; 25 | reg signed [16-1:0] new_y; 26 | reg signed [16-1:0] new_angle; 27 | 28 | wire sign; 29 | wire signed [16-1:0] shifted_x; 30 | wire signed [16-1:0] shifted_y; 31 | 32 | assign sign = angle_in[16-1]; // angle sign bit 33 | assign shifted_x = x_in >>> SHIFT; 34 | assign shifted_y = y_in >>> SHIFT; 35 | 36 | always @(*) 37 | begin 38 | new_x = sign ? (x_in + shifted_y) : (x_in - shifted_y); 39 | new_y = sign ? (y_in - shifted_x) : (y_in + shifted_x); 40 | new_angle = sign ? (angle_in + angle_adj) : (angle_in - angle_adj); 41 | end 42 | 43 | always @(posedge clk) 44 | begin 45 | if (rst_n == 1'b0) 46 | begin 47 | x_out <= 0; 48 | y_out <= 0; 49 | angle_out <= 0; 50 | end 51 | else begin 52 | x_out <= new_x; 53 | y_out <= new_y; 54 | angle_out <= new_angle; 55 | end 56 | end 57 | 58 | endmodule 59 | 60 | 61 | module cordic_10_16(clk, rst_n, angle_in, cos_out, sin_out); 62 | 63 | // inputs 64 | input clk; 65 | input rst_n; 66 | input signed [16-1:0] angle_in; 67 | 68 | // outputs 69 | output signed [16-1:0] cos_out; 70 | output signed [16-1:0] sin_out; 71 | 72 | // internal signals 73 | reg signed [16-1:0] x_in; 74 | reg signed [16-1:0] y_in; 75 | reg signed [16-1:0] z_in; 76 | 77 | wire signed [16-1:0] xbus [0:10-1]; 78 | wire signed [16-1:0] ybus [0:10-1]; 79 | wire signed [16-1:0] zbus [0:10-1]; 80 | 81 | assign cos_out = xbus[10-1]; 82 | assign sin_out = ybus[10-1]; 83 | 84 | always @(*) 85 | begin 86 | case($unsigned(angle_in[16-1:16-2])) 87 | 2'b00: 88 | begin 89 | x_in <= 16'd19897; 90 | y_in <= 0; 91 | z_in <= angle_in; 92 | end 93 | 2'b11: 94 | begin 95 | x_in <= 16'd19897; 96 | y_in <= 0; 97 | z_in <= angle_in; 98 | end 99 | 2'b01: 100 | begin 101 | x_in <= 0; 102 | y_in <= 16'd19897; 103 | z_in <= $signed({2'b00, angle_in[16-3:0]}); 104 | end 105 | 2'b10: 106 | begin 107 | x_in <= 0; 108 | y_in <= -16'd19897; 109 | z_in <= $signed({2'b11, angle_in[16-3:0]}); 110 | end 111 | endcase 112 | end 113 | 114 | // generate instances of cordic_stage 115 | cordic_stage_16 #(0) stage0(clk, rst_n, x_in, y_in, z_in, 16'sd8192, xbus[0], ybus[0], zbus[0]); 116 | cordic_stage_16 #(1) stage1(clk, rst_n, xbus[0], ybus[0], zbus[0], 16'sd4836, xbus[1], ybus[1], zbus[1]); 117 | cordic_stage_16 #(2) stage2(clk, rst_n, xbus[1], ybus[1], zbus[1], 16'sd2555, xbus[2], ybus[2], zbus[2]); 118 | cordic_stage_16 #(3) stage3(clk, rst_n, xbus[2], ybus[2], zbus[2], 16'sd1297, xbus[3], ybus[3], zbus[3]); 119 | cordic_stage_16 #(4) stage4(clk, rst_n, xbus[3], ybus[3], zbus[3], 16'sd651, xbus[4], ybus[4], zbus[4]); 120 | cordic_stage_16 #(5) stage5(clk, rst_n, xbus[4], ybus[4], zbus[4], 16'sd326, xbus[5], ybus[5], zbus[5]); 121 | cordic_stage_16 #(6) stage6(clk, rst_n, xbus[5], ybus[5], zbus[5], 16'sd163, xbus[6], ybus[6], zbus[6]); 122 | cordic_stage_16 #(7) stage7(clk, rst_n, xbus[6], ybus[6], zbus[6], 16'sd81, xbus[7], ybus[7], zbus[7]); 123 | cordic_stage_16 #(8) stage8(clk, rst_n, xbus[7], ybus[7], zbus[7], 16'sd41, xbus[8], ybus[8], zbus[8]); 124 | cordic_stage_16 #(9) stage9(clk, rst_n, xbus[8], ybus[8], zbus[8], 16'sd20, xbus[9], ybus[9], zbus[9]); 125 | 126 | 127 | endmodule 128 | -------------------------------------------------------------------------------- /benchmarks/counter.v: -------------------------------------------------------------------------------- 1 | // Quick blinking a LED 2 | 3 | /* module */ 4 | module counter ( 5 | input rst, 6 | input clk, 7 | output led 8 | 9 | ); 10 | 11 | /* reg */ 12 | reg [7:0] counter = 0; 13 | reg state; 14 | 15 | /* assign */ 16 | assign led = counter[7]; 17 | 18 | /* always */ 19 | always @ (posedge clk) begin 20 | if (!rst) begin 21 | counter <= 8'b0; 22 | end else begin 23 | counter <= counter + 1'b1; 24 | end 25 | end 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /benchmarks/counter_tb.v: -------------------------------------------------------------------------------- 1 | module counter_tb (); 2 | 3 | reg clk, rst; 4 | wire led; 5 | 6 | counter DUT ( 7 | .rst(rst), 8 | .clk(clk), 9 | .led(led) 10 | ); 11 | 12 | initial begin 13 | $dumpfile("counter.vcd"); 14 | $dumpvars(0,counter_tb); 15 | clk = 1'b0; 16 | rst = 1'b0; 17 | repeat(4) #10 clk = ~clk; 18 | rst = 1'b1; 19 | repeat(1024) #10 clk = ~clk; 20 | end 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /benchmarks/dspmac_16_40.v: -------------------------------------------------------------------------------- 1 | // DSP multiply-and-accumulate block without saturation 2 | // Author: Niels A. Moseley 3 | 4 | module dspmac_16_40( 5 | input clk, 6 | input rst_n, 7 | input [1:0] opcode, 8 | input signed [16-1:0] a_in, 9 | input signed [16-1:0] b_in, 10 | output signed [40-1:0] accu_out 11 | ); 12 | 13 | reg signed [40-1:0] accu; 14 | 15 | parameter [1:0] OP_CLR = 2'b00, 16 | OP_MUL = 2'b01, 17 | OP_MAC = 2'b10, 18 | OP_NOP = 2'b11; 19 | 20 | always @(posedge clk or negedge rst_n) 21 | begin 22 | if (rst_n == 1'b0) 23 | accu <= 40'd0; // set accumulator to zero 24 | else 25 | begin 26 | case(opcode) 27 | OP_CLR: 28 | accu <= 0; 29 | OP_MUL: 30 | accu <= a_in*b_in; 31 | OP_MAC: 32 | accu <= accu+a_in*b_in; 33 | OP_NOP: 34 | accu <= accu; 35 | default: 36 | accu <= accu; 37 | endcase 38 | end 39 | end 40 | 41 | assign accu_out = accu; 42 | 43 | endmodule 44 | -------------------------------------------------------------------------------- /benchmarks/dspmac_16_40_tb.v: -------------------------------------------------------------------------------- 1 | // Testbench for sddac.v 2 | // Author: Niels A. Moseley 3 | 4 | `include "constants.vams" 5 | 6 | module tb; 7 | 8 | reg clk = 0; 9 | reg rst_n = 0; 10 | reg [1:0] opcode = 2'b11; // nop 11 | reg signed [15:0] a_bus = 0; 12 | reg signed [15:0] b_bus = 0; 13 | wire signed [39:0] result; 14 | 15 | // clock generation 16 | always #1 clk=~clk; 17 | 18 | // devices under test 19 | dspmac_16_40 dut(clk, rst_n, opcode, a_bus, b_bus, result); 20 | 21 | initial 22 | begin 23 | $dumpfile("dspmac_16_40.vcd"); 24 | $dumpvars; 25 | 26 | opcode = 2'b00; //CLR 27 | 28 | #4 rst_n = 1'b1; 29 | a_bus = 16'd32767; 30 | b_bus = 16'd32767; 31 | opcode = 2'b01; // MUL 32 | #2 opcode = 2'b10; // MAC 33 | #2 opcode = 2'b11; // NOP 34 | #2 opcode = 2'b11; // NOP 35 | #2 $finish; 36 | 37 | end 38 | 39 | endmodule 40 | -------------------------------------------------------------------------------- /benchmarks/picorv32_tb.v: -------------------------------------------------------------------------------- 1 | // This is free and unencumbered software released into the public domain. 2 | // 3 | // Anyone is free to copy, modify, publish, use, compile, sell, or 4 | // distribute this software, either in source code form or as a compiled 5 | // binary, for any purpose, commercial or non-commercial, and by any 6 | // means. 7 | 8 | `timescale 1 ns / 1 ps 9 | 10 | module testbench; 11 | reg clk = 1; 12 | reg resetn = 0; 13 | wire trap; 14 | 15 | always #5 clk = ~clk; 16 | 17 | initial begin 18 | $dumpfile("picorv32.vcd"); 19 | $dumpvars(0, testbench); 20 | repeat (100) @(posedge clk); 21 | resetn <= 1; 22 | repeat (1000) @(posedge clk); 23 | $finish; 24 | end 25 | 26 | wire mem_valid; 27 | wire mem_instr; 28 | reg mem_ready; 29 | wire [31:0] mem_addr; 30 | wire [31:0] mem_wdata; 31 | wire [3:0] mem_wstrb; 32 | reg [31:0] mem_rdata; 33 | 34 | always @(posedge clk) begin 35 | if (mem_valid && mem_ready) begin 36 | if (mem_instr) 37 | $display("ifetch 0x%08x: 0x%08x", mem_addr, mem_rdata); 38 | else if (mem_wstrb) 39 | $display("write 0x%08x: 0x%08x (wstrb=%b)", mem_addr, mem_wdata, mem_wstrb); 40 | else 41 | $display("read 0x%08x: 0x%08x", mem_addr, mem_rdata); 42 | end 43 | end 44 | 45 | picorv32 #( 46 | ) uut ( 47 | .clk (clk ), 48 | .resetn (resetn ), 49 | .trap (trap ), 50 | .mem_valid (mem_valid ), 51 | .mem_instr (mem_instr ), 52 | .mem_ready (mem_ready ), 53 | .mem_addr (mem_addr ), 54 | .mem_wdata (mem_wdata ), 55 | .mem_wstrb (mem_wstrb ), 56 | .mem_rdata (mem_rdata ) 57 | ); 58 | 59 | reg [31:0] memory [0:255]; 60 | 61 | initial begin 62 | memory[0] = 32'h 3fc00093; // li x1,1020 63 | memory[1] = 32'h 0000a023; // sw x0,0(x1) 64 | memory[2] = 32'h 0000a103; // loop: lw x2,0(x1) 65 | memory[3] = 32'h 00110113; // addi x2,x2,1 66 | memory[4] = 32'h 0020a023; // sw x2,0(x1) 67 | memory[5] = 32'h ff5ff06f; // j 68 | end 69 | 70 | always @(posedge clk) begin 71 | mem_ready <= 0; 72 | if (mem_valid && !mem_ready) begin 73 | if (mem_addr < 1024) begin 74 | mem_ready <= 1; 75 | mem_rdata <= memory[mem_addr >> 2]; 76 | if (mem_wstrb[0]) memory[mem_addr >> 2][ 7: 0] <= mem_wdata[ 7: 0]; 77 | if (mem_wstrb[1]) memory[mem_addr >> 2][15: 8] <= mem_wdata[15: 8]; 78 | if (mem_wstrb[2]) memory[mem_addr >> 2][23:16] <= mem_wdata[23:16]; 79 | if (mem_wstrb[3]) memory[mem_addr >> 2][31:24] <= mem_wdata[31:24]; 80 | end 81 | /* add memory-mapped IO here */ 82 | end 83 | end 84 | endmodule 85 | -------------------------------------------------------------------------------- /benchmarks/pwm256.v: -------------------------------------------------------------------------------- 1 | // 256-level PWM generator 2 | // Author: Niels A. Moseley 3 | // Symbiotic EDA / Moseley Instruments 4 | // 10-11-2018 5 | 6 | module pwm256( 7 | input clk, 8 | input rst_n, 9 | input [7:0] d_in, 10 | output pwm_out 11 | ); 12 | 13 | reg signed [7:0] counter; 14 | 15 | assign pwm_out = counter > d_in; 16 | 17 | always @(posedge clk or negedge rst_n) 18 | begin 19 | if (rst_n == 1'b0) 20 | begin 21 | counter <= 8'd0; 22 | end 23 | else 24 | begin 25 | counter <= counter + 8'd1; 26 | end 27 | end 28 | 29 | endmodule 30 | -------------------------------------------------------------------------------- /benchmarks/pwm256_tb.v: -------------------------------------------------------------------------------- 1 | // Testbench for 256-level PWM generator 2 | // Author: Niels A. Moseley 3 | // Symbiotic EDA / Moseley Instruments 4 | // 10-11-2018 5 | 6 | module tb; 7 | 8 | reg clk = 0; 9 | reg rst_n = 0; 10 | reg [7:0] d_in = 8'd128; 11 | wire pwm; 12 | 13 | // clock generation 14 | always #1 clk=~clk; 15 | 16 | // devices under test 17 | pwm256 dut(clk, rst_n, d_in, pwm); 18 | 19 | initial 20 | begin 21 | $dumpfile("pwm256.vcd"); 22 | $dumpvars; 23 | 24 | #4 rst_n = 1'b1; 25 | #516 d_in = 8'd10; 26 | #1028 d_in = 8'd246; 27 | #1540 $finish; 28 | 29 | end 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /benchmarks/pwmled.v: -------------------------------------------------------------------------------- 1 | // 128-level breathing LED 2 | // Author: Pepijn de Vos 3 | 4 | module pwmled( 5 | input clk, 6 | input rst_n, 7 | output pwm_out 8 | ); 9 | 10 | reg [15:0] counter; 11 | 12 | wire [6:0] idx; 13 | wire [6:0] level; 14 | wire polarity; 15 | 16 | assign polarity = counter[15]; 17 | assign idx = counter[6:0]; 18 | assign level = counter[15:8]; 19 | assign pwm_out = polarity ^ (idx > level); 20 | 21 | always @(posedge clk) 22 | begin 23 | if (!rst_n) 24 | begin 25 | counter <= 16'b0000000000000000; 26 | end 27 | else 28 | begin 29 | counter <= counter + 1'b1; 30 | end 31 | end 32 | 33 | endmodule 34 | -------------------------------------------------------------------------------- /benchmarks/pwmled_tb.v: -------------------------------------------------------------------------------- 1 | // Testbench for 256-level PWM generator 2 | // Author: Niels A. Moseley 3 | // Symbiotic EDA / Moseley Instruments 4 | // 10-11-2018 5 | 6 | module tb; 7 | 8 | reg clk = 0; 9 | reg rst_n = 0; 10 | wire pwm; 11 | 12 | // clock generation 13 | always #1 clk=~clk; 14 | 15 | // devices under test 16 | pwmled dut(clk, rst_n, pwm); 17 | 18 | initial 19 | begin 20 | $dumpfile("pwmled.vcd"); 21 | $dumpvars; 22 | 23 | #4 rst_n = 1'b1; 24 | #154000 $finish; 25 | 26 | end 27 | 28 | endmodule 29 | -------------------------------------------------------------------------------- /benchmarks/sddac.v: -------------------------------------------------------------------------------- 1 | // Second order sigma-delta dac 2 | // 3 | // For benchmarking purposes only -- don't use this for an actual design. 4 | // There are far more performant architectures. 5 | // 6 | // Author: Niels A. Moseley, n.a.moseley@moseleyinstruments.com 7 | // 8 | 9 | `ifdef DEBUG_SDDAC 10 | `include "constants.vams" 11 | `endif 12 | 13 | module sddac(clk, rst_n, sig_in, sd_out); 14 | 15 | // inputs 16 | input clk; // clock 17 | input rst_n; // synchronous reset, active low 18 | input signed [15:0] sig_in; // 16 bits in Q(1,15) format 19 | 20 | // outputs 21 | output reg sd_out = 0; 22 | 23 | // internal signals 24 | reg signed [17:0] state1 = 0; // Q(1,17) 25 | reg signed [19:0] state2 = 0; // Q(1,19) 26 | reg signed [16:0] state1_in; // Q(0,17) 27 | reg signed [18:0] state2_in; // Q(0,19) 28 | reg signed [20:0] quant_in; // Q(2,19) 29 | reg signed [16:0] qq; 30 | reg [7:0] lfsr_reg = 0; 31 | reg quantizer; 32 | wire lfsr_fb; 33 | 34 | // linear feedback shift register feedback 35 | assign lfsr_fb = (lfsr_reg[4] ^ lfsr_reg[2]); 36 | 37 | // combination process 38 | always @(*) 39 | begin 40 | `ifdef DEBUG_SDDAC 41 | qq = $signed(quantizer ? -17'h8000 : 17'h8000); 42 | `endif 43 | quant_in = state2 + $signed(lfsr_fb ? -21'h4000 : 21'h4000); 44 | quantizer = quant_in[20]; 45 | state1_in = sig_in - $signed(quantizer ? -17'h8000 : 17'h8000); // Q(-1,17) - Q(0,17) -> Q(0,17) 46 | state2_in = state1 - $signed(quantizer ? -19'h10000 : 19'h10000); // Q(-1,19) - Q(0,19) -> Q(0,19) 47 | end 48 | 49 | // clocked process 50 | always @(posedge clk) 51 | begin 52 | if (rst_n == 1'b0) 53 | begin 54 | state1 <= 0; 55 | state2 <= 0; 56 | lfsr_reg <= 8'hff; 57 | end 58 | else begin 59 | `ifdef DEBUG_SDDAC 60 | $display("feedback : %f", qq*$pow(2.0,-15)); 61 | $display("state1_in: %f", state1_in*$pow(2.0,-17)); 62 | $display("state2_in: %f", state2_in*$pow(2.0,-19)); 63 | $display(""); 64 | `endif 65 | state1 <= state1 + $signed({ state1_in[16], state1_in}); 66 | state2 <= state2 + $signed({ state2_in[18], state2_in}); 67 | sd_out <= !quantizer; 68 | lfsr_reg <= {lfsr_reg[6:0], lfsr_fb}; 69 | end 70 | end 71 | 72 | endmodule 73 | -------------------------------------------------------------------------------- /benchmarks/sddac_tb.v: -------------------------------------------------------------------------------- 1 | // Testbench for sddac.v 2 | // Author: Niels A. Moseley 3 | 4 | `include "constants.vams" 5 | 6 | module tb; 7 | 8 | reg clk = 0; 9 | reg rst_n = 0; 10 | reg signed [15:0] sig = 0; 11 | wire dac_out; 12 | 13 | real phase = 0.0; 14 | integer fhandle; 15 | 16 | // clock generation 17 | always #1 clk=~clk; 18 | 19 | // devices under test 20 | sddac dut(clk, rst_n, sig, dac_out); 21 | 22 | initial 23 | begin 24 | $dumpfile("sddac.vcd"); 25 | $dumpvars; 26 | 27 | fhandle = $fopen("sddac_out.txt","w"); 28 | 29 | #4 rst_n = 1'b1; 30 | 31 | #526288 $finish; // 2^18 + 1000 startup samples 32 | end 33 | 34 | always @(posedge clk) 35 | begin 36 | if (rst_n == 1'b1) 37 | begin 38 | $fwrite(fhandle, "%d\n", dac_out); 39 | sig <= $sin(`M_TWO_PI*phase)*10000.0; 40 | phase <= phase + 0.001; 41 | end 42 | end 43 | 44 | endmodule 45 | -------------------------------------------------------------------------------- /benchmarks/shifter64.v: -------------------------------------------------------------------------------- 1 | // Formal Verification with SymbiYosys: 2 | // sby -f shifter64.sby default 3 | // sby -f shifter64.sby nofslrw 4 | // sby -f shifter64.sby nowmode 5 | // 6 | // Area estimate with Yosys: 7 | // yosys -p "synth -top shifter64 -flatten; abc -g cmos2; stat" shifter64.v 8 | // yosys -D NO_FSLRW -p "synth -top shifter64 -flatten; abc -g cmos2; stat" shifter64.v 9 | // yosys -D NO_WMODE -p "synth -top shifter64 -flatten; abc -g cmos2; stat" shifter64.v 10 | // 11 | // default nofslrw nowmode 12 | // LUT-4 680 680 707 13 | // LUT-6 386 386 427 14 | // Gates 2118 2105 2084 15 | // 16 | // NAND 1851 1837 1693 17 | // NOR 238 259 380 18 | // NOT 59 18 22 19 | // 20 | // (NOT = 1/2 gate, use "abc -lut 4" or "abc -lut 6" for LUT counts) 21 | 22 | module shifter64 ( 23 | input [63:0] A, B, 24 | output [63:0] X, 25 | input [6:0] shamt, 26 | input insn30, 27 | input insn29, 28 | input insn26, 29 | input insn14, 30 | input insn3 31 | ); 32 | `ifdef NO_WMODE 33 | wire wmode = 0; 34 | `else 35 | wire wmode = insn3; 36 | `endif 37 | reg [63:0] bb; 38 | reg [6:0] sh; 39 | 40 | always @* begin 41 | sh = shamt; 42 | bb = B; 43 | 44 | if (wmode || !insn26) 45 | sh[6] = 0; 46 | 47 | `ifdef NO_FSLRW 48 | if (wmode) 49 | sh[5] = 0; 50 | `else 51 | if (wmode && !insn26) 52 | sh[5] = 0; 53 | `endif 54 | 55 | if (insn14) 56 | sh = -sh; 57 | 58 | if (!insn26) begin 59 | casez ({insn30, insn29}) 60 | 2'b 0z: bb = {64{insn29}}; 61 | 2'b 10: bb = {64{wmode ? A[31] : A[63]}}; 62 | 2'b 11: bb = A; 63 | endcase 64 | end 65 | end 66 | 67 | shifter64_datapath datapath ( 68 | .A (A ), 69 | .B (bb ), 70 | .X (X ), 71 | .shamt (sh ), 72 | .wmode (wmode) 73 | ); 74 | endmodule 75 | 76 | module shifter64_datapath ( 77 | input [63:0] A, B, 78 | output [63:0] X, 79 | input [6:0] shamt, 80 | input wmode 81 | ); 82 | reg [127:0] tmp, tmp2; 83 | 84 | wire shamt_5_0 = wmode ? 0 : shamt[5]; 85 | wire shamt_5_1 = wmode ? 1 : shamt[5]; 86 | wire shamt_5_2 = wmode ? 0 : shamt[5]; 87 | wire shamt_5_3 = wmode ? 1 : shamt[5]; 88 | 89 | wire shamt_6_0 = wmode ? shamt[5] : shamt[6]; 90 | wire shamt_6_1 = wmode ? !shamt[5] : shamt[6]; 91 | wire shamt_6_2 = wmode ? !shamt[5] : shamt[6]; 92 | wire shamt_6_3 = wmode ? shamt[5] : shamt[6]; 93 | 94 | always @* begin 95 | tmp = {B, A}; 96 | 97 | `ifdef NO_WMODE 98 | if (shamt[5]) tmp = {tmp[95:0], tmp[127:96]}; 99 | if (shamt[6]) tmp = {tmp[63:0], tmp[127:64]}; 100 | `else 101 | tmp2 = tmp; 102 | if (shamt_5_0) tmp2[ 31: 0] = tmp[127:96]; 103 | if (shamt_5_1) tmp2[ 63:32] = tmp[ 31: 0]; 104 | if (shamt_5_2) tmp2[ 95:64] = tmp[ 63:32]; 105 | if (shamt_5_3) tmp2[127:96] = tmp[ 95:64]; 106 | 107 | tmp = tmp2; 108 | if (shamt_6_0) tmp[ 31: 0] = tmp2[ 95:64]; 109 | if (shamt_6_1) tmp[ 63:32] = tmp2[127:96]; 110 | if (shamt_6_2) tmp[ 95:64] = tmp2[ 31: 0]; 111 | if (shamt_6_3) tmp[127:96] = tmp2[ 63:32]; 112 | `endif 113 | if (shamt[4]) tmp = {tmp[111:0], tmp[127:112]}; 114 | if (shamt[3]) tmp = {tmp[119:0], tmp[127:120]}; 115 | if (shamt[2]) tmp = {tmp[123:0], tmp[127:124]}; 116 | if (shamt[1]) tmp = {tmp[125:0], tmp[127:126]}; 117 | if (shamt[0]) tmp = {tmp[126:0], tmp[127:127]}; 118 | end 119 | 120 | assign X = tmp; 121 | endmodule 122 | 123 | `ifdef FORMAL 124 | module shifter64_props ( 125 | input [63:0] A, B, 126 | output [63:0] X, 127 | input [6:0] shamt, 128 | input insn30, 129 | input insn29, 130 | input insn26, 131 | input insn14, 132 | input insn3 133 | ); 134 | shifter64 uut ( 135 | .A (A ), 136 | .B (B ), 137 | .X (X ), 138 | .shamt (shamt ), 139 | .insn30 (insn30), 140 | .insn29 (insn29), 141 | .insn26 (insn26), 142 | .insn14 (insn14), 143 | .insn3 (insn3 ) 144 | ); 145 | 146 | wire [31:0] AL = A; 147 | wire [31:0] BL = B; 148 | wire [31:0] XL = X; 149 | 150 | wire [6:0] sh7 = shamt; 151 | wire [5:0] sh6 = shamt; 152 | wire [4:0] sh5 = shamt; 153 | 154 | wire [63:0] X_SLL = A << sh6; 155 | wire [63:0] X_SRL = A >> sh6; 156 | wire [63:0] X_SRA = $signed(A) >>> sh6; 157 | wire [63:0] X_SLO = ~(~A << sh6); 158 | wire [63:0] X_SRO = ~(~A >> sh6); 159 | wire [63:0] X_ROL = ({A,A} << sh6) >> 64; 160 | wire [63:0] X_ROR = ({A,A} >> sh6); 161 | wire [63:0] X_FSL = ({A,B,A,B} << sh7) >> (64+128); 162 | wire [63:0] X_FSR = ({B,A,B,A} >> sh7); 163 | 164 | wire [31:0] X_SLLW = AL << sh5; 165 | wire [31:0] X_SRLW = AL >> sh5; 166 | wire [31:0] X_SRAW = $signed(AL) >>> sh5; 167 | wire [31:0] X_SLOW = ~(~AL << sh5); 168 | wire [31:0] X_SROW = ~(~AL >> sh5); 169 | wire [31:0] X_ROLW = ({AL,AL} << sh5) >> 32; 170 | wire [31:0] X_RORW = ({AL,AL} >> sh5); 171 | wire [31:0] X_FSLW = ({AL,BL,AL,BL} << sh6) >> (32+64); 172 | wire [31:0] X_FSRW = ({BL,AL,BL,AL} >> sh6); 173 | 174 | always @* begin 175 | casez ({insn30, insn29, insn26, insn14, insn3}) 176 | 5'b 00000: assert(X == X_SLL); 177 | 5'b 00010: assert(X == X_SRL); 178 | 5'b 10010: assert(X == X_SRA); 179 | 5'b 01000: assert(X == X_SLO); 180 | 5'b 01010: assert(X == X_SRO); 181 | 5'b 11000: assert(X == X_ROL); 182 | 5'b 11000: assert(X == X_ROR); 183 | 5'b zz100: assert(X == X_FSL); 184 | 5'b zz110: assert(X == X_FSR); 185 | 186 | `ifndef NO_WMODE 187 | 5'b 00001: assert(XL == X_SLLW); 188 | 5'b 00011: assert(XL == X_SRLW); 189 | 5'b 10011: assert(XL == X_SRAW); 190 | 5'b 01001: assert(XL == X_SLOW); 191 | 5'b 01011: assert(XL == X_SROW); 192 | 5'b 11001: assert(XL == X_ROLW); 193 | 5'b 11001: assert(XL == X_RORW); 194 | `ifndef NO_FSLRW 195 | 5'b zz101: assert(XL == X_FSLW); 196 | 5'b zz111: assert(XL == X_FSRW); 197 | `endif 198 | `endif 199 | endcase 200 | end 201 | endmodule 202 | `endif 203 | -------------------------------------------------------------------------------- /benchmarks/smartbextdep.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Clifford Wolf 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | * 16 | */ 17 | 18 | module smartbextdep ( 19 | input clock, 20 | input bdep, 21 | input [31:0] rs1, 22 | input [31:0] rs2, 23 | output reg [31:0] rd 24 | ); 25 | wire din_mode; 26 | wire [31:0] din_value; 27 | wire [31:0] din_mask; 28 | wire [31:0] dout_result; 29 | 30 | assign din_mode = bdep; 31 | assign din_value = rs1; 32 | assign din_mask = rs2; 33 | 34 | smartbextdep_direct smartbextdep_direct_inst ( 35 | .din_mode (din_mode ), 36 | .din_value (din_value ), 37 | .din_mask (din_mask ), 38 | .dout_result(dout_result) 39 | ); 40 | 41 | always @(posedge clock) begin 42 | rd <= dout_result; 43 | end 44 | endmodule 45 | 46 | // ======================================================================== 47 | 48 | `define smartbextdep_bfly_idx_a(k, i) ((2 << (k))*((i)/(1 << (k))) + (i)%(1 << (k))) 49 | `define smartbextdep_bfly_idx_b(k, i) (`smartbextdep_bfly_idx_a(k, i) + (1<<(k))) 50 | 51 | module smartbextdep_direct ( 52 | input din_mode, 53 | input [31:0] din_value, 54 | input [31:0] din_mask, 55 | output [31:0] dout_result 56 | ); 57 | wire [15:0] decoder_s1, decoder_s2, decoder_s4; 58 | wire [15:0] decoder_s8, decoder_s16, decoder_s32; 59 | 60 | smartbextdep_decoder decoder ( 61 | .mask (din_mask ), 62 | .s1 (decoder_s1 ), 63 | .s2 (decoder_s2 ), 64 | .s4 (decoder_s4 ), 65 | .s8 (decoder_s8 ), 66 | .s16 (decoder_s16) 67 | ); 68 | 69 | wire [31:0] result_fwd; 70 | wire [31:0] result_bwd; 71 | 72 | smartbextdep_bfly_fwd butterfly_fwd ( 73 | .din (din_value ), 74 | .s1 (~decoder_s1 ), 75 | .s2 (~decoder_s2 ), 76 | .s4 (~decoder_s4 ), 77 | .s8 (~decoder_s8 ), 78 | .s16 (~decoder_s16), 79 | .dout (result_fwd ) 80 | ); 81 | 82 | smartbextdep_bfly_bwd butterfly_bwd ( 83 | .din (din_value & din_mask), 84 | .s1 (~decoder_s1 ), 85 | .s2 (~decoder_s2 ), 86 | .s4 (~decoder_s4 ), 87 | .s8 (~decoder_s8 ), 88 | .s16 (~decoder_s16), 89 | .dout (result_bwd ) 90 | ); 91 | 92 | assign dout_result = din_mode ? (result_fwd & din_mask) : result_bwd; 93 | endmodule 94 | 95 | // ======================================================================== 96 | 97 | module smartbextdep_lrotcz #( 98 | parameter integer N = 1, 99 | parameter integer M = 1 100 | ) ( 101 | input [7:0] din, 102 | output [M-1:0] dout 103 | ); 104 | wire [2*M-1:0] mask = {M{1'b1}}; 105 | assign dout = (mask << din[N-1:0]) >> M; 106 | endmodule 107 | 108 | module smartbextdep_decoder ( 109 | input clock, 110 | input enable, 111 | input [31:0] mask, 112 | output [15:0] s1, s2, s4, s8, s16 113 | ); 114 | wire [8*32-1:0] ppsdata; 115 | 116 | smartbextdep_pps32 pps_core ( 117 | .din (mask), 118 | .dout (ppsdata) 119 | ); 120 | 121 | genvar i; 122 | generate 123 | for (i = 0; i < 32/2; i = i+1) begin:stage1 124 | smartbextdep_lrotcz #(.N(1), .M(1)) lrotc_zero ( 125 | .din(ppsdata[8*(2*i + 1 - 1) +: 8]), 126 | .dout(s1[i]) 127 | ); 128 | end 129 | 130 | for (i = 0; i < 32/4; i = i+1) begin:stage2 131 | smartbextdep_lrotcz #(.N(2), .M(2)) lrotc_zero ( 132 | .din(ppsdata[8*(4*i + 2 - 1) +: 8]), 133 | .dout(s2[2*i +: 2]) 134 | ); 135 | end 136 | 137 | for (i = 0; i < 32/8; i = i+1) begin:stage4 138 | smartbextdep_lrotcz #(.N(3), .M(4)) lrotc_zero ( 139 | .din(ppsdata[8*(8*i + 4 - 1) +: 8]), 140 | .dout(s4[4*i +: 4]) 141 | ); 142 | end 143 | 144 | for (i = 0; i < 32/16; i = i+1) begin:stage8 145 | smartbextdep_lrotcz #(.N(4), .M(8)) lrotc_zero ( 146 | .din(ppsdata[8*(16*i + 8 - 1) +: 8]), 147 | .dout(s8[8*i +: 8]) 148 | ); 149 | end 150 | 151 | for (i = 0; i < 32/32; i = i+1) begin:stage16 152 | smartbextdep_lrotcz #(.N(5), .M(16)) lrotc_zero ( 153 | .din(ppsdata[8*(32*i + 16 - 1) +: 8]), 154 | .dout(s16[16*i +: 16]) 155 | ); 156 | end 157 | endgenerate 158 | endmodule 159 | 160 | module smartbextdep_bfly_fwd ( 161 | input [31:0] din, 162 | input [15:0] s1, s2, s4, s8, s16, 163 | output [31:0] dout 164 | ); 165 | reg [31:0] butterfly; 166 | assign dout = butterfly; 167 | 168 | integer k, i; 169 | always @* begin 170 | butterfly = din; 171 | 172 | for (i = 0; i < 16; i = i+1) 173 | if (s16[i]) {butterfly[`smartbextdep_bfly_idx_a(4, i)], butterfly[`smartbextdep_bfly_idx_b(4, i)]} = 174 | {butterfly[`smartbextdep_bfly_idx_b(4, i)], butterfly[`smartbextdep_bfly_idx_a(4, i)]}; 175 | 176 | for (i = 0; i < 16; i = i+1) 177 | if (s8[i]) {butterfly[`smartbextdep_bfly_idx_a(3, i)], butterfly[`smartbextdep_bfly_idx_b(3, i)]} = 178 | {butterfly[`smartbextdep_bfly_idx_b(3, i)], butterfly[`smartbextdep_bfly_idx_a(3, i)]}; 179 | 180 | for (i = 0; i < 16; i = i+1) 181 | if (s4[i]) {butterfly[`smartbextdep_bfly_idx_a(2, i)], butterfly[`smartbextdep_bfly_idx_b(2, i)]} = 182 | {butterfly[`smartbextdep_bfly_idx_b(2, i)], butterfly[`smartbextdep_bfly_idx_a(2, i)]}; 183 | 184 | for (i = 0; i < 16; i = i+1) 185 | if (s2[i]) {butterfly[`smartbextdep_bfly_idx_a(1, i)], butterfly[`smartbextdep_bfly_idx_b(1, i)]} = 186 | {butterfly[`smartbextdep_bfly_idx_b(1, i)], butterfly[`smartbextdep_bfly_idx_a(1, i)]}; 187 | 188 | for (i = 0; i < 16; i = i+1) 189 | if (s1[i]) {butterfly[`smartbextdep_bfly_idx_a(0, i)], butterfly[`smartbextdep_bfly_idx_b(0, i)]} = 190 | {butterfly[`smartbextdep_bfly_idx_b(0, i)], butterfly[`smartbextdep_bfly_idx_a(0, i)]}; 191 | end 192 | endmodule 193 | 194 | module smartbextdep_bfly_bwd ( 195 | input [31:0] din, 196 | input [15:0] s1, s2, s4, s8, s16, 197 | output [31:0] dout 198 | ); 199 | reg [31:0] butterfly; 200 | assign dout = butterfly; 201 | 202 | integer k, i; 203 | always @* begin 204 | butterfly = din; 205 | 206 | for (i = 0; i < 16; i = i+1) 207 | if (s1[i]) {butterfly[`smartbextdep_bfly_idx_a(0, i)], butterfly[`smartbextdep_bfly_idx_b(0, i)]} = 208 | {butterfly[`smartbextdep_bfly_idx_b(0, i)], butterfly[`smartbextdep_bfly_idx_a(0, i)]}; 209 | 210 | for (i = 0; i < 16; i = i+1) 211 | if (s2[i]) {butterfly[`smartbextdep_bfly_idx_a(1, i)], butterfly[`smartbextdep_bfly_idx_b(1, i)]} = 212 | {butterfly[`smartbextdep_bfly_idx_b(1, i)], butterfly[`smartbextdep_bfly_idx_a(1, i)]}; 213 | 214 | for (i = 0; i < 16; i = i+1) 215 | if (s4[i]) {butterfly[`smartbextdep_bfly_idx_a(2, i)], butterfly[`smartbextdep_bfly_idx_b(2, i)]} = 216 | {butterfly[`smartbextdep_bfly_idx_b(2, i)], butterfly[`smartbextdep_bfly_idx_a(2, i)]}; 217 | 218 | for (i = 0; i < 16; i = i+1) 219 | if (s8[i]) {butterfly[`smartbextdep_bfly_idx_a(3, i)], butterfly[`smartbextdep_bfly_idx_b(3, i)]} = 220 | {butterfly[`smartbextdep_bfly_idx_b(3, i)], butterfly[`smartbextdep_bfly_idx_a(3, i)]}; 221 | 222 | for (i = 0; i < 16; i = i+1) 223 | if (s16[i]) {butterfly[`smartbextdep_bfly_idx_a(4, i)], butterfly[`smartbextdep_bfly_idx_b(4, i)]} = 224 | {butterfly[`smartbextdep_bfly_idx_b(4, i)], butterfly[`smartbextdep_bfly_idx_a(4, i)]}; 225 | end 226 | endmodule 227 | 228 | module smartbextdep_pps32 ( 229 | input [31:0] din, 230 | output [255:0] dout 231 | ); 232 | function [15:0] carry_save_add; 233 | input [15:0] a, b; 234 | reg [7:0] x, y; 235 | begin 236 | x = a[15:8] ^ a[7:0] ^ b[7:0]; 237 | y = ((a[15:8] & a[7:0]) | (a[15:8] & b[7:0]) | (a[7:0] & b[7:0])) << 1; 238 | carry_save_add[7:0] = x ^ y ^ b[15:8]; 239 | carry_save_add[15:8] = ((x & y) | (x & b[15:8]) | (y & b[15:8])) << 1; 240 | end 241 | endfunction 242 | function [7:0] carry_save_get; 243 | input [15:0] a; 244 | begin 245 | carry_save_get = a[7:0] + a[15:8]; 246 | end 247 | endfunction 248 | // inputs 249 | wire [15:0] e0s0 = {15'b0, din[0 +: 1]}; 250 | wire [15:0] e1s0 = {15'b0, din[1 +: 1]}; 251 | wire [15:0] e2s0 = {15'b0, din[2 +: 1]}; 252 | wire [15:0] e3s0 = {15'b0, din[3 +: 1]}; 253 | wire [15:0] e4s0 = {15'b0, din[4 +: 1]}; 254 | wire [15:0] e5s0 = {15'b0, din[5 +: 1]}; 255 | wire [15:0] e6s0 = {15'b0, din[6 +: 1]}; 256 | wire [15:0] e7s0 = {15'b0, din[7 +: 1]}; 257 | wire [15:0] e8s0 = {15'b0, din[8 +: 1]}; 258 | wire [15:0] e9s0 = {15'b0, din[9 +: 1]}; 259 | wire [15:0] e10s0 = {15'b0, din[10 +: 1]}; 260 | wire [15:0] e11s0 = {15'b0, din[11 +: 1]}; 261 | wire [15:0] e12s0 = {15'b0, din[12 +: 1]}; 262 | wire [15:0] e13s0 = {15'b0, din[13 +: 1]}; 263 | wire [15:0] e14s0 = {15'b0, din[14 +: 1]}; 264 | wire [15:0] e15s0 = {15'b0, din[15 +: 1]}; 265 | wire [15:0] e16s0 = {15'b0, din[16 +: 1]}; 266 | wire [15:0] e17s0 = {15'b0, din[17 +: 1]}; 267 | wire [15:0] e18s0 = {15'b0, din[18 +: 1]}; 268 | wire [15:0] e19s0 = {15'b0, din[19 +: 1]}; 269 | wire [15:0] e20s0 = {15'b0, din[20 +: 1]}; 270 | wire [15:0] e21s0 = {15'b0, din[21 +: 1]}; 271 | wire [15:0] e22s0 = {15'b0, din[22 +: 1]}; 272 | wire [15:0] e23s0 = {15'b0, din[23 +: 1]}; 273 | wire [15:0] e24s0 = {15'b0, din[24 +: 1]}; 274 | wire [15:0] e25s0 = {15'b0, din[25 +: 1]}; 275 | wire [15:0] e26s0 = {15'b0, din[26 +: 1]}; 276 | wire [15:0] e27s0 = {15'b0, din[27 +: 1]}; 277 | wire [15:0] e28s0 = {15'b0, din[28 +: 1]}; 278 | wire [15:0] e29s0 = {15'b0, din[29 +: 1]}; 279 | wire [15:0] e30s0 = {15'b0, din[30 +: 1]}; 280 | wire [15:0] e31s0 = {15'b0, din[31 +: 1]}; 281 | // forward pass 282 | wire [15:0] e1s1 = carry_save_add(e1s0, e0s0); 283 | wire [15:0] e3s1 = carry_save_add(e3s0, e2s0); 284 | wire [15:0] e5s1 = carry_save_add(e5s0, e4s0); 285 | wire [15:0] e7s1 = carry_save_add(e7s0, e6s0); 286 | wire [15:0] e9s1 = carry_save_add(e9s0, e8s0); 287 | wire [15:0] e11s1 = carry_save_add(e11s0, e10s0); 288 | wire [15:0] e13s1 = carry_save_add(e13s0, e12s0); 289 | wire [15:0] e15s1 = carry_save_add(e15s0, e14s0); 290 | wire [15:0] e17s1 = carry_save_add(e17s0, e16s0); 291 | wire [15:0] e19s1 = carry_save_add(e19s0, e18s0); 292 | wire [15:0] e21s1 = carry_save_add(e21s0, e20s0); 293 | wire [15:0] e23s1 = carry_save_add(e23s0, e22s0); 294 | wire [15:0] e25s1 = carry_save_add(e25s0, e24s0); 295 | wire [15:0] e27s1 = carry_save_add(e27s0, e26s0); 296 | wire [15:0] e29s1 = carry_save_add(e29s0, e28s0); 297 | wire [15:0] e31s1 = carry_save_add(e31s0, e30s0); 298 | wire [15:0] e3s2 = carry_save_add(e3s1, e1s1); 299 | wire [15:0] e7s2 = carry_save_add(e7s1, e5s1); 300 | wire [15:0] e11s2 = carry_save_add(e11s1, e9s1); 301 | wire [15:0] e15s2 = carry_save_add(e15s1, e13s1); 302 | wire [15:0] e19s2 = carry_save_add(e19s1, e17s1); 303 | wire [15:0] e23s2 = carry_save_add(e23s1, e21s1); 304 | wire [15:0] e27s2 = carry_save_add(e27s1, e25s1); 305 | wire [15:0] e31s2 = carry_save_add(e31s1, e29s1); 306 | wire [15:0] e7s3 = carry_save_add(e7s2, e3s2); 307 | wire [15:0] e15s3 = carry_save_add(e15s2, e11s2); 308 | wire [15:0] e23s3 = carry_save_add(e23s2, e19s2); 309 | wire [15:0] e31s3 = carry_save_add(e31s2, e27s2); 310 | wire [15:0] e15s4 = carry_save_add(e15s3, e7s3); 311 | wire [15:0] e31s4 = carry_save_add(e31s3, e23s3); 312 | wire [15:0] e31s5 = carry_save_add(e31s4, e15s4); 313 | // backward pass 314 | wire [15:0] e23s6 = carry_save_add(e23s3, e15s4); 315 | wire [15:0] e11s7 = carry_save_add(e11s2, e7s3); 316 | wire [15:0] e19s7 = carry_save_add(e19s2, e15s4); 317 | wire [15:0] e27s7 = carry_save_add(e27s2, e23s6); 318 | wire [15:0] e5s8 = carry_save_add(e5s1, e3s2); 319 | wire [15:0] e9s8 = carry_save_add(e9s1, e7s3); 320 | wire [15:0] e13s8 = carry_save_add(e13s1, e11s7); 321 | wire [15:0] e17s8 = carry_save_add(e17s1, e15s4); 322 | wire [15:0] e21s8 = carry_save_add(e21s1, e19s7); 323 | wire [15:0] e25s8 = carry_save_add(e25s1, e23s6); 324 | wire [15:0] e29s8 = carry_save_add(e29s1, e27s7); 325 | wire [15:0] e2s9 = carry_save_add(e2s0, e1s1); 326 | wire [15:0] e4s9 = carry_save_add(e4s0, e3s2); 327 | wire [15:0] e6s9 = carry_save_add(e6s0, e5s8); 328 | wire [15:0] e8s9 = carry_save_add(e8s0, e7s3); 329 | wire [15:0] e10s9 = carry_save_add(e10s0, e9s8); 330 | wire [15:0] e12s9 = carry_save_add(e12s0, e11s7); 331 | wire [15:0] e14s9 = carry_save_add(e14s0, e13s8); 332 | wire [15:0] e16s9 = carry_save_add(e16s0, e15s4); 333 | wire [15:0] e18s9 = carry_save_add(e18s0, e17s8); 334 | wire [15:0] e20s9 = carry_save_add(e20s0, e19s7); 335 | wire [15:0] e22s9 = carry_save_add(e22s0, e21s8); 336 | wire [15:0] e24s9 = carry_save_add(e24s0, e23s6); 337 | wire [15:0] e26s9 = carry_save_add(e26s0, e25s8); 338 | wire [15:0] e28s9 = carry_save_add(e28s0, e27s7); 339 | wire [15:0] e30s9 = carry_save_add(e30s0, e29s8); 340 | // outputs 341 | assign dout[0 +: 8] = carry_save_get(e0s0); 342 | assign dout[8 +: 8] = carry_save_get(e1s1); 343 | assign dout[16 +: 8] = carry_save_get(e2s9); 344 | assign dout[24 +: 8] = carry_save_get(e3s2); 345 | assign dout[32 +: 8] = carry_save_get(e4s9); 346 | assign dout[40 +: 8] = carry_save_get(e5s8); 347 | assign dout[48 +: 8] = carry_save_get(e6s9); 348 | assign dout[56 +: 8] = carry_save_get(e7s3); 349 | assign dout[64 +: 8] = carry_save_get(e8s9); 350 | assign dout[72 +: 8] = carry_save_get(e9s8); 351 | assign dout[80 +: 8] = carry_save_get(e10s9); 352 | assign dout[88 +: 8] = carry_save_get(e11s7); 353 | assign dout[96 +: 8] = carry_save_get(e12s9); 354 | assign dout[104 +: 8] = carry_save_get(e13s8); 355 | assign dout[112 +: 8] = carry_save_get(e14s9); 356 | assign dout[120 +: 8] = carry_save_get(e15s4); 357 | assign dout[128 +: 8] = carry_save_get(e16s9); 358 | assign dout[136 +: 8] = carry_save_get(e17s8); 359 | assign dout[144 +: 8] = carry_save_get(e18s9); 360 | assign dout[152 +: 8] = carry_save_get(e19s7); 361 | assign dout[160 +: 8] = carry_save_get(e20s9); 362 | assign dout[168 +: 8] = carry_save_get(e21s8); 363 | assign dout[176 +: 8] = carry_save_get(e22s9); 364 | assign dout[184 +: 8] = carry_save_get(e23s6); 365 | assign dout[192 +: 8] = carry_save_get(e24s9); 366 | assign dout[200 +: 8] = carry_save_get(e25s8); 367 | assign dout[208 +: 8] = carry_save_get(e26s9); 368 | assign dout[216 +: 8] = carry_save_get(e27s7); 369 | assign dout[224 +: 8] = carry_save_get(e28s9); 370 | assign dout[232 +: 8] = carry_save_get(e29s8); 371 | assign dout[240 +: 8] = carry_save_get(e30s9); 372 | assign dout[248 +: 8] = carry_save_get(e31s5); 373 | endmodule 374 | -------------------------------------------------------------------------------- /bram.rules: -------------------------------------------------------------------------------- 1 | bram IDT7132_1x1MEM8 2 | init 0 3 | abits 10 4 | dbits 8 5 | groups 2 6 | ports 1 1 7 | wrmode 1 0 8 | enable 2 2 9 | transp 0 1 10 | clocks 1 0 11 | clkpol 1 1 12 | endbram 13 | 14 | match IDT7132_1x1MEM8 15 | make_transp 16 | make_outreg 17 | endmatch 18 | -------------------------------------------------------------------------------- /equiv.ys: -------------------------------------------------------------------------------- 1 | read_liberty 74series.lib 2 | read_verilog +/simcells.v 3 | 4 | equiv_make \$_MUX_ \74AC11257_4x1MUX2 equiv2 5 | equiv_induct equiv2 6 | equiv_status -assert equiv2 7 | 8 | equiv_make \$_MUX4_ \74AC153_2x1MUX4 equiv4 9 | equiv_induct equiv4 10 | equiv_status -assert equiv4 11 | 12 | equiv_make \$_MUX8_ \74AC151_1x1MUX8 equiv8 13 | equiv_induct equiv8 14 | equiv_status -assert equiv8 15 | -------------------------------------------------------------------------------- /ic_count.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import fileinput 3 | import math 4 | import re 5 | 6 | IC_LIST = dict() 7 | 8 | for line in fileinput.input(): 9 | match = re.search(r"^\s*(\S+)_(\d+)x(\d*)\S+\s*(\d+)", line) 10 | 11 | if not match: 12 | continue 13 | 14 | part_number, gates_per_ic, gates_per_combo, combo_count = match.groups() 15 | 16 | if gates_per_combo == '': 17 | gates_per_combo = "1" 18 | 19 | if part_number not in IC_LIST: 20 | IC_LIST[part_number] = ( 21 | (int(combo_count) * int(gates_per_combo)) 22 | / int(gates_per_ic)) 23 | else: 24 | IC_LIST[part_number] += ( 25 | (int(combo_count) * int(gates_per_combo)) 26 | / int(gates_per_ic)) 27 | 28 | TOTAL_ICs = 0 29 | 30 | for part, count in IC_LIST.items(): 31 | count = math.ceil(count) 32 | TOTAL_ICs += count 33 | print("{}: {}".format(part, count)) 34 | 35 | print() 36 | print("Total: {}".format(TOTAL_ICs)) 37 | -------------------------------------------------------------------------------- /kicad/74xx.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | $CMP 7400 4 | D quad 2-input NAND gate 5 | K TTL nand 2-input 6 | F http://www.ti.com/lit/gpn/sn7400 7 | $ENDCMP 8 | # 9 | $CMP 7402 10 | D quad 2-input NOR gate 11 | K TTL Nor2 12 | F http://www.ti.com/lit/gpn/sn7402 13 | $ENDCMP 14 | # 15 | $CMP 74469 16 | D 8-bit synchronous up/down counter, parallel load and hold capability (obsolete) 17 | K counter 18 | F http://www.ti.com/lit/gpn/sn74469 19 | $ENDCMP 20 | # 21 | $CMP 74AHC04 22 | D Hex Inverter 23 | K AHCMOS not inv 24 | F https://assets.nexperia.com/documents/data-sheet/74AHC_AHCT04.pdf 25 | $ENDCMP 26 | # 27 | $CMP 74AHC244 28 | D 8-bit Buffer/Line Driver 3-state 29 | K AHCMOS BUFFER 3State 30 | F https://assets.nexperia.com/documents/data-sheet/74AHC_AHCT244.pdf 31 | $ENDCMP 32 | # 33 | $CMP 74AHC273 34 | D 8-bit D Flip-Flop, reset 35 | K AHCMOS DFF DFF8 36 | F https://assets.nexperia.com/documents/data-sheet/74AHC_AHCT273.pdf 37 | $ENDCMP 38 | # 39 | $CMP 74AHC374 40 | D 8-bit Register, 3-state outputs 41 | K AHCMOS DFF DFF8 REG 3State 42 | F https://assets.nexperia.com/documents/data-sheet/74AHC_AHCT374.pdf 43 | $ENDCMP 44 | # 45 | $CMP 74AHCT04 46 | D Hex Inverter 47 | K AHCTMOS not inv 48 | F https://assets.nexperia.com/documents/data-sheet/74AHC_AHCT04.pdf 49 | $ENDCMP 50 | # 51 | $CMP 74AHCT123 52 | D Dual retriggerable monostable multivibrator 53 | K TTL monostable, multivibrator 54 | F http://www.ti.com/lit/gpn/sn74ahct123a 55 | $ENDCMP 56 | # 57 | $CMP 74AHCT244 58 | D 8-bit Buffer/Line Driver 3-state 59 | K AHCTMOS BUFFER 3State 60 | F https://assets.nexperia.com/documents/data-sheet/74AHC_AHCT244.pdf 61 | $ENDCMP 62 | # 63 | $CMP 74AHCT273 64 | D 8-bit D Flip-Flop, reset 65 | K AHCTMOS DFF DFF8 66 | F https://assets.nexperia.com/documents/data-sheet/74AHC_AHCT273.pdf 67 | $ENDCMP 68 | # 69 | $CMP 74AHCT374 70 | D 8-bit Register, 3-state outputs 71 | K AHCTMOS DFF DFF8 REG 3State 72 | F https://assets.nexperia.com/documents/data-sheet/74AHC_AHCT374.pdf 73 | $ENDCMP 74 | # 75 | $CMP 74CBTLV3257 76 | D Quad 1:2 FET Multiplexer/Demultiplexer, Low-Voltage 77 | K mux demux low-voltage 78 | F http://www.ti.com/lit/ds/symlink/sn74cbtlv3257.pdf 79 | $ENDCMP 80 | # 81 | $CMP 74CBTLV3861 82 | D Low-voltage 10-bit FET Bus switch 83 | K bus 84 | F http://www.ti.com/lit/gpn/sn74cbtlv3861 85 | $ENDCMP 86 | # 87 | $CMP 74HC00 88 | D quad 2-input NAND gate 89 | K HCMOS nand 2-input 90 | F http://www.ti.com/lit/gpn/sn74hc00 91 | $ENDCMP 92 | # 93 | $CMP 74HC02 94 | D quad 2-input NOR gate 95 | K HCMOS Nor2 96 | F http://www.ti.com/lit/gpn/sn74hc02 97 | $ENDCMP 98 | # 99 | $CMP 74HC04 100 | D Hex Inverter 101 | K HCMOS not inv 102 | F https://assets.nexperia.com/documents/data-sheet/74HC_HCT04.pdf 103 | $ENDCMP 104 | # 105 | $CMP 74HC123 106 | D Dual retriggerable monostable multivibrator 107 | K TTL monostable, multivibrator 108 | F https://assets.nexperia.com/documents/data-sheet/74HC_HCT123.pdf 109 | $ENDCMP 110 | # 111 | $CMP 74HC137 112 | D 3-to-8 line decoder/multiplexer with address latches, DIP-16/SOIC-16/SSOP-16 113 | K demux 114 | F http://www.ti.com/lit/ds/symlink/cd74hc237.pdf 115 | $ENDCMP 116 | # 117 | $CMP 74HC14 118 | D Hex inverter schmitt trigger 119 | K HCMOS not inverter 120 | F http://www.ti.com/lit/gpn/sn74HC14 121 | $ENDCMP 122 | # 123 | $CMP 74HC164 124 | D 8-bit serial-in parallel-out shift register 125 | K 8-bit shift register 126 | F https://assets.nexperia.com/documents/data-sheet/74HC_HCT164.pdf 127 | $ENDCMP 128 | # 129 | $CMP 74HC237 130 | D 3-to-8 line decoder/multiplexer with address latches, DIP-16/SOIC-16/SSOP-16 131 | K demux 132 | F http://www.ti.com/lit/ds/symlink/cd74hc237.pdf 133 | $ENDCMP 134 | # 135 | $CMP 74HC240 136 | D 8-bit Buffer/Line Driver 3-state Inverting 137 | K TTL BUFFER 3State inv 138 | F https://assets.nexperia.com/documents/data-sheet/74HC_HCT240.pdf 139 | $ENDCMP 140 | # 141 | $CMP 74HC244 142 | D 8-bit Buffer/Line Driver 3-state 143 | K HCMOS BUFFER 3State 144 | F https://assets.nexperia.com/documents/data-sheet/74HC_HCT244.pdf 145 | $ENDCMP 146 | # 147 | $CMP 74HC245 148 | D Octal BUS Transceivers, 3-State outputs 149 | K HCMOS BUS 3State 150 | F http://www.ti.com/lit/gpn/sn74HC245 151 | $ENDCMP 152 | # 153 | $CMP 74HC273 154 | D 8-bit D Flip-Flop, reset 155 | K HCMOS DFF DFF8 156 | F https://assets.nexperia.com/documents/data-sheet/74HC_HCT273.pdf 157 | $ENDCMP 158 | # 159 | $CMP 74HC374 160 | D 8-bit Register, 3-state outputs 161 | K HCMOS DFF DFF8 REG 3State 162 | F https://www.ti.com/lit/ds/symlink/cd74hct374.pdf 163 | $ENDCMP 164 | # 165 | $CMP 74HC4024 166 | D 7-stage binary ripple counter, SOIC-14 167 | K binary counter 168 | F https://assets.nexperia.com/documents/data-sheet/74HC4024.pdf 169 | $ENDCMP 170 | # 171 | $CMP 74HC4051 172 | D 8-channel analog multiplexer/demultiplexer, DIP-16/SOIC-16/TSSOP-16 173 | K HCMOS Multiplexer Demultiplexer Analog 174 | F http://www.ti.com/lit/ds/symlink/cd74hc4051.pdf 175 | $ENDCMP 176 | # 177 | $CMP 74HC590 178 | D 8-bit Binary Counter with Output Register 3-State Outputs, SOIC-16/TSSOP-16 179 | K HCMOS Counter 3State 180 | F https://assets.nexperia.com/documents/data-sheet/74HC590.pdf 181 | $ENDCMP 182 | # 183 | $CMP 74HC590A 184 | D 8-bit Binary Counter with Output Register 3-State Outputs, DIP-16/SOIC-16/SOIC-16W 185 | K HCMOS Counter 3State 186 | F http://www.ti.com/lit/ds/symlink/sn74hc590a.pdf 187 | $ENDCMP 188 | # 189 | $CMP 74HC595 190 | D 8-bit serial in/out Shift Register 3-State Outputs 191 | K HCMOS SR 3State 192 | F http://www.ti.com/lit/ds/symlink/sn74hc595.pdf 193 | $ENDCMP 194 | # 195 | $CMP 74HC596 196 | D 8-bit serial in/out Shift Register Open Collector Outputs 197 | K HCMOS SR OpenCollector 198 | F https://assets.nexperia.com/documents/data-sheet/74HC_HCT595.pdf 199 | $ENDCMP 200 | # 201 | $CMP 74HC7014 202 | D Hex non-inverting buffer with precision Schmitt Trigger inputs, SOIC-14 203 | K Hex non-inverting Schmitt buffer 204 | F https://assets.nexperia.com/documents/data-sheet/74HC7014.pdf 205 | $ENDCMP 206 | # 207 | $CMP 74HC74 208 | D Dual D Flip-flop, Set & Reset 209 | K TTL DFF 210 | F 74xx/74hc_hct74.pdf 211 | $ENDCMP 212 | # 213 | $CMP 74HC86 214 | D Quad 2-input XOR 215 | K TTL XOR2 216 | F http://www.ti.com/lit/gpn/sn74HC86 217 | $ENDCMP 218 | # 219 | $CMP 74HCT00 220 | D quad 2-input NAND gate 221 | K HCTMOS nand 2-input 222 | F http://www.ti.com/lit/gpn/sn74hct00 223 | $ENDCMP 224 | # 225 | $CMP 74HCT02 226 | D quad 2-input NOR gate 227 | K HCTMOS Nor2 228 | F http://www.ti.com/lit/gpn/sn74hct02 229 | $ENDCMP 230 | # 231 | $CMP 74HCT04 232 | D Hex Inverter 233 | K HCTMOS not inv 234 | F https://assets.nexperia.com/documents/data-sheet/74HC_HCT04.pdf 235 | $ENDCMP 236 | # 237 | $CMP 74HCT123 238 | D Dual retriggerable monostable multivibrator 239 | K TTL monostable, multivibrator 240 | F https://assets.nexperia.com/documents/data-sheet/74HC_HCT123.pdf 241 | $ENDCMP 242 | # 243 | $CMP 74HCT137 244 | D 3-to-8 line decoder/multiplexer with address latches, DIP-16/SOIC-16/SSOP-16 245 | K demux 246 | F http://www.ti.com/lit/ds/symlink/cd74hc237.pdf 247 | $ENDCMP 248 | # 249 | $CMP 74HCT164 250 | D 8-bit serial-in parallel-out shift register 251 | K 8-bit shift register 252 | F https://assets.nexperia.com/documents/data-sheet/74HC_HCT164.pdf 253 | $ENDCMP 254 | # 255 | $CMP 74HCT237 256 | D 3-to-8 line decoder/multiplexer with address latches, DIP-16/SOIC-16/SSOP-16 257 | K demux 258 | F http://www.ti.com/lit/ds/symlink/cd74hc237.pdf 259 | $ENDCMP 260 | # 261 | $CMP 74HCT240 262 | D 8-bit buffer; 3-state; inverting 263 | K octal buffer line driver inverting 264 | F https://assets.nexperia.com/documents/data-sheet/74HC_HCT240.pdf 265 | $ENDCMP 266 | # 267 | $CMP 74HCT244 268 | D 8-bit Buffer/Line Driver 3-state 269 | K HCTMOS BUFFER 3State 270 | F https://assets.nexperia.com/documents/data-sheet/74HC_HCT244.pdf 271 | $ENDCMP 272 | # 273 | $CMP 74HCT273 274 | D 8-bit D Flip-Flop, reset 275 | K HCTMOS DFF DFF8 276 | F https://assets.nexperia.com/documents/data-sheet/74HC_HCT273.pdf 277 | $ENDCMP 278 | # 279 | $CMP 74HCT374 280 | D 8-bit Register, 3-state outputs 281 | K HCTMOS DFF DFF8 REG 3State 282 | F https://www.ti.com/lit/ds/symlink/cd74hct374.pdf 283 | $ENDCMP 284 | # 285 | $CMP 74HCT4051 286 | D 8-channel analog multiplexer/demultiplexer, DIP-16/SOIC-16/TSSOP-16 287 | K TTL Multiplexer Demultiplexer Analog 288 | F http://www.ti.com/lit/ds/symlink/cd74hct4051.pdf 289 | $ENDCMP 290 | # 291 | $CMP 74HCT541 292 | D 8-bit Buffer/Line Driver 3-state outputs 293 | K TTL BUFFER 3State BUS 294 | F http://www.ti.com/lit/gpn/sn74HCT541 295 | $ENDCMP 296 | # 297 | $CMP 74HCT574 298 | D 8-bit Register, 3-state outputs 299 | K TTL REG DFF DFF8 3State 300 | F http://www.ti.com/lit/gpn/sn74HCT574 301 | $ENDCMP 302 | # 303 | $CMP 74HCT595 304 | D 8-bit serial in/out Shift Register 3-State Outputs 305 | K HCTMOS SR 3State 306 | F https://assets.nexperia.com/documents/data-sheet/74HC_HCT595.pdf 307 | $ENDCMP 308 | # 309 | $CMP 74HCT596 310 | D 8-bit serial in/out Shift Register Open Collector Outputs 311 | K HCTMOS SR OpenCollector 312 | F https://assets.nexperia.com/documents/data-sheet/74HC_HCT595.pdf 313 | $ENDCMP 314 | # 315 | $CMP 74LCX07 316 | D CMOS hex buffer (open drain) with 5V tolerant inputs 317 | K CMOS hex buffer 318 | F www.st.com/resource/en/datasheet/74lcx07.pdf 319 | $ENDCMP 320 | # 321 | $CMP 74LS00 322 | D quad 2-input NAND gate 323 | K TTL nand 2-input 324 | F http://www.ti.com/lit/gpn/sn74ls00 325 | $ENDCMP 326 | # 327 | $CMP 74LS01 328 | D quad 2-input NAND gate, open collector outputs NRND 329 | K TTL nand 2-input open collector 330 | F http://www.nteinc.com/specs/7400to7499/pdf/nte74LS01.pdf 331 | $ENDCMP 332 | # 333 | $CMP 74LS02 334 | D quad 2-input NOR gate 335 | K TTL Nor2 336 | F http://www.ti.com/lit/gpn/sn74ls02 337 | $ENDCMP 338 | # 339 | $CMP 74LS03 340 | D Quad 2-input NAND open collector 341 | K TTL Nand2 OpenColl 342 | F http://www.ti.com/lit/gpn/sn74LS03 343 | $ENDCMP 344 | # 345 | $CMP 74LS04 346 | D Hex Inverter 347 | K TTL not inv 348 | F http://www.ti.com/lit/gpn/sn74LS04 349 | $ENDCMP 350 | # 351 | $CMP 74LS05 352 | D Inverter Open Collect 353 | K TTL not inv OpenCol 354 | F http://www.ti.com/lit/gpn/sn74LS05 355 | $ENDCMP 356 | # 357 | $CMP 74LS06 358 | D Inverter Open Collect 359 | K TTL not inv OpenCol 360 | F http://www.ti.com/lit/gpn/sn74LS06 361 | $ENDCMP 362 | # 363 | $CMP 74LS06N 364 | D Inverter Open Collect 365 | K TTL not inv OpenCol 366 | F http://www.ti.com/lit/gpn/sn74LS06N 367 | $ENDCMP 368 | # 369 | $CMP 74LS07 370 | D Hex Buffers and Drivers With Open Collector High Voltage Outputs 371 | K TTL hex buffer OpenCol 372 | F www.ti.com/lit/ds/symlink/sn74ls07.pdf 373 | $ENDCMP 374 | # 375 | $CMP 74LS08 376 | D Quad And2 377 | K TTL and2 378 | F http://www.ti.com/lit/gpn/sn74LS08 379 | $ENDCMP 380 | # 381 | $CMP 74LS09 382 | D Quad 2-input AND Open Collect 383 | K TTL and2 OpenCol 384 | F http://www.ti.com/lit/gpn/sn74LS09 385 | $ENDCMP 386 | # 387 | $CMP 74LS10 388 | D Triple 3-input NAND 389 | K TTL Nand3 390 | F http://www.ti.com/lit/gpn/sn74LS10 391 | $ENDCMP 392 | # 393 | $CMP 74LS107 394 | D Dual JK Flip-Flop, reset 395 | K TTL JK 396 | F http://www.ti.com/lit/gpn/sn74LS107 397 | $ENDCMP 398 | # 399 | $CMP 74LS109 400 | D Dual JK Flip-Flop, Set & Reset 401 | K TTL JK 402 | F http://www.ti.com/lit/gpn/sn74LS109 403 | $ENDCMP 404 | # 405 | $CMP 74LS11 406 | D Triple 3-input AND 407 | K TTL And3 408 | F http://www.ti.com/lit/gpn/sn74LS11 409 | $ENDCMP 410 | # 411 | $CMP 74LS112 412 | D dual JK Flip-Flop, Set & Reset 413 | K TTL JK 414 | F http://www.ti.com/lit/gpn/sn74LS112 415 | $ENDCMP 416 | # 417 | $CMP 74LS113 418 | D dual JK flip-flop, Set 419 | K TTL JK 420 | F http://www.ti.com/lit/gpn/sn74LS113 421 | $ENDCMP 422 | # 423 | $CMP 74LS114 424 | D Dual JK flip-flop, common Clock & Reset, Set 425 | K TTL JK 426 | F http://www.ti.com/lit/gpn/sn74LS114 427 | $ENDCMP 428 | # 429 | $CMP 74LS12 430 | D Triple 3-input NAND Open Collector 431 | K TTL Nand3 OpenCol 432 | F http://www.ti.com/lit/gpn/sn74LS12 433 | $ENDCMP 434 | # 435 | $CMP 74LS121 436 | D monostable multivibrator with Schmitt-trigger inputs 437 | K monostable 438 | F http://www.ti.com/lit/gpn/sn74121 439 | $ENDCMP 440 | # 441 | $CMP 74LS122 442 | D Retriggerable Monostable 443 | K TTL monostable 444 | F http://www.ti.com/lit/gpn/sn74LS122 445 | $ENDCMP 446 | # 447 | $CMP 74LS123 448 | D Dual retriggerable Monostable 449 | K TTL monostable 450 | F http://www.ti.com/lit/gpn/sn74LS123 451 | $ENDCMP 452 | # 453 | $CMP 74LS125 454 | D Quad buffer 3-State outputs 455 | K TTL buffer 3State 456 | F http://www.ti.com/lit/gpn/sn74LS125 457 | $ENDCMP 458 | # 459 | $CMP 74LS126 460 | D Quad buffer 3-State outputs 461 | K TTL Buffer 3State 462 | F http://www.ti.com/lit/gpn/sn74LS126 463 | $ENDCMP 464 | # 465 | $CMP 74LS13 466 | D Dual 4-input NAND Schmitt trigger 467 | K TTL Nand4 468 | F http://www.ti.com/lit/gpn/sn74LS13 469 | $ENDCMP 470 | # 471 | $CMP 74LS132 472 | D Quad 2-input NAND Schmitt trigger 473 | K TTL Nand2 474 | F http://www.ti.com/lit/gpn/sn74LS132 475 | $ENDCMP 476 | # 477 | $CMP 74LS133 478 | D NAND 13-input 479 | K TTL Nand13 480 | F http://www.ti.com/lit/gpn/sn74LS133 481 | $ENDCMP 482 | # 483 | $CMP 74LS136 484 | D Quad 2-input XOR Open Collector 485 | K TTL XOR2 OpenCol 486 | F http://www.ti.com/lit/ds/symlink/sn54ls136.pdf 487 | $ENDCMP 488 | # 489 | $CMP 74LS137 490 | D Decoder 3 to 8, address latches 491 | K TTL DECOD8 DECOD 492 | F http://www.ti.com/lit/gpn/sn74LS137 493 | $ENDCMP 494 | # 495 | $CMP 74LS138 496 | D Decoder 3 to 8 active low outputs 497 | K TTL DECOD DECOD8 498 | F http://www.ti.com/lit/gpn/sn74LS138 499 | $ENDCMP 500 | # 501 | $CMP 74LS139 502 | D Dual Decoder 1 of 4, Active low outputs 503 | K TTL DECOD4 504 | F http://www.ti.com/lit/gpn/sn74LS139 505 | $ENDCMP 506 | # 507 | $CMP 74LS14 508 | D Hex inverter schmitt trigger 509 | K TTL not inverter 510 | F http://www.ti.com/lit/gpn/sn74LS14 511 | $ENDCMP 512 | # 513 | $CMP 74LS145 514 | D Decoder 1 to 10, Open Collector 515 | K TTL DECOD10 OpenColl 516 | F http://www.ti.com/lit/gpn/sn74LS145 517 | $ENDCMP 518 | # 519 | $CMP 74LS147 520 | D Priority Encoder, 10 to 4 521 | K TTL ENCOD 522 | F http://www.ti.com/lit/gpn/sn74LS147 523 | $ENDCMP 524 | # 525 | $CMP 74LS148 526 | D Priority Encoder 3 to 8 cascadable 527 | K TTL ENCOD 528 | F http://www.ti.com/lit/gpn/sn74LS148 529 | $ENDCMP 530 | # 531 | $CMP 74LS15 532 | D Triple 3-input AND 533 | K TTL And3 534 | F http://www.ti.com/lit/gpn/sn74LS15 535 | $ENDCMP 536 | # 537 | $CMP 74LS151 538 | D Multiplexer 8 to 1 539 | K TTL MUX8 540 | F http://www.ti.com/lit/gpn/sn74LS151 541 | $ENDCMP 542 | # 543 | $CMP 74LS153 544 | D Dual Multiplexer 4 to 1 545 | K TTL Mux4 546 | F http://www.ti.com/lit/gpn/sn74LS153 547 | $ENDCMP 548 | # 549 | $CMP 74LS154 550 | D Decoder 4 to 16 551 | K TTL DECOD16 DECOD 552 | F http://www.ti.com/lit/gpn/sn74LS154 553 | $ENDCMP 554 | # 555 | $CMP 74LS155 556 | D Dual 2 to 4 lines Decoder/Demultiplexer 557 | K TTL DECOD8 DECOD4 DEMUX4 DEMUX8 DEMUX DECOD 558 | F http://www.ti.com/lit/gpn/sn74LS155 559 | $ENDCMP 560 | # 561 | $CMP 74LS156 562 | D Dual 2 to 4 lines Decoder/Demultiplexer, Open Collector 563 | K TTL DECOD8 DECOD4 DEMUX4 DEMUX8 OpenCol 564 | F http://www.ti.com/lit/gpn/sn74LS156 565 | $ENDCMP 566 | # 567 | $CMP 74LS157 568 | D Quad 2 to 1 line Multiplexer 569 | K TTL MUX MUX2 570 | F http://www.ti.com/lit/gpn/sn74LS157 571 | $ENDCMP 572 | # 573 | $CMP 74LS158 574 | D Quad 2 to 1 multiplexer 575 | K TTL Mux MUX2 576 | F http://www.ti.com/lit/gpn/sn74LS158 577 | $ENDCMP 578 | # 579 | $CMP 74LS160 580 | D Synchronous 4-bit programmable decimal Counter 581 | K TTL CNT CNT4 582 | F http://www.ti.com/lit/gpn/sn74LS160 583 | $ENDCMP 584 | # 585 | $CMP 74LS161 586 | D Synchronous 4-bit programmable binary Counter 587 | K TTL CNT CNT4 588 | F http://www.ti.com/lit/gpn/sn74LS161 589 | $ENDCMP 590 | # 591 | $CMP 74LS162 592 | D Synchronous 4-bit programmable decimal Counter 593 | K TTL CNT CNT4 594 | F http://www.ti.com/lit/gpn/sn74LS162 595 | $ENDCMP 596 | # 597 | $CMP 74LS163 598 | D Synchronous 4-bit programmable binary Counter 599 | K TTL CNT CNT4 600 | F http://www.ti.com/lit/gpn/sn74LS163 601 | $ENDCMP 602 | # 603 | $CMP 74LS165 604 | D Shift Register 8-bit, parallel load 605 | K TTL SR SR8 606 | F http://www.ti.com/lit/gpn/sn74LS165 607 | $ENDCMP 608 | # 609 | $CMP 74LS166 610 | D Shift Register 8-bit, parallel load 611 | K TTL SR SR8 612 | F http://www.ti.com/lit/gpn/sn74LS166 613 | $ENDCMP 614 | # 615 | $CMP 74LS168 616 | D Synchronous 4-bit Up/Down Decimal counter 617 | K TTL CNT CNT4 618 | F http://www.ti.com/lit/gpn/sn74LS168 619 | $ENDCMP 620 | # 621 | $CMP 74LS169 622 | D Synchronous 4-bit Up/Down binary counter 623 | K TTL CNT CNT4 624 | F http://www.ti.com/lit/gpn/sn74LS169 625 | $ENDCMP 626 | # 627 | $CMP 74LS170 628 | D 4 x 4 Register Files Open Collector 629 | K TTL Register OpenCol 630 | F http://www.ti.com/lit/gpn/sn74LS170 631 | $ENDCMP 632 | # 633 | $CMP 74LS173 634 | D 4-bit D-type Register, 3 state out 635 | K TTL REG REG4 3State DFF 636 | F http://www.ti.com/lit/gpn/sn74LS173 637 | $ENDCMP 638 | # 639 | $CMP 74LS174 640 | D Hex D-type Flip-Flop, reset 641 | K TTL REG REG6 DFF 642 | F http://www.ti.com/lit/gpn/sn74LS174 643 | $ENDCMP 644 | # 645 | $CMP 74LS175 646 | D 4-bit D Flip-Flop, reset 647 | K TTL REG REG4 DFF 648 | F http://www.ti.com/lit/gpn/sn74LS175 649 | $ENDCMP 650 | # 651 | $CMP 74LS181 652 | D Arithmetic logic unit 653 | K TTL ALU ARITH 654 | F 74xx/74F181.pdf 655 | $ENDCMP 656 | # 657 | $CMP 74LS182 658 | D Carry generator 659 | K TTL ALU ARITH 660 | F http://www.ti.com/lit/gpn/sn74LS182 661 | $ENDCMP 662 | # 663 | $CMP 74LS190 664 | D 4-bit Synchronous Up/Down BCD Counter 665 | K TTL CNT CNT4 666 | F http://www.ti.com/lit/gpn/sn74LS190 667 | $ENDCMP 668 | # 669 | $CMP 74LS191 670 | D 4-bit Synchronous Up/Down binary Counter 671 | K TTL CNT CNT4 672 | F http://www.ti.com/lit/gpn/sn74LS191 673 | $ENDCMP 674 | # 675 | $CMP 74LS192 676 | D Synchronous 4-bit Up/Down (2 clk) counter 677 | K TTL CNT CNT4 678 | F http://www.ti.com/lit/gpn/sn74LS192 679 | $ENDCMP 680 | # 681 | $CMP 74LS193 682 | D Synchronous 4-bit Up/Down (2 clk) counter 683 | K TTL CNT CNT4 684 | F http://www.ti.com/lit/gpn/sn74LS193 685 | $ENDCMP 686 | # 687 | $CMP 74LS194 688 | D Shift Register 4-bit Bidirectional 689 | K TTL RS SR4 690 | F http://www.ti.com/lit/gpn/sn74LS194 691 | $ENDCMP 692 | # 693 | $CMP 74LS195 694 | D Shift Register 4-bit, parallel 695 | K TTL SR SR4 696 | F http://www.ti.com/lit/gpn/sn74LS195 697 | $ENDCMP 698 | # 699 | $CMP 74LS196 700 | D 4 (3+1)-bit presettable BCD counter 701 | K TTL CNT CNT4 702 | F http://www.ti.com/lit/gpn/sn74LS196 703 | $ENDCMP 704 | # 705 | $CMP 74LS197 706 | D 4 (3+1)-bit presettable binary counter 707 | K TTL CNT CNT4 708 | F http://www.ti.com/lit/gpn/sn74LS197 709 | $ENDCMP 710 | # 711 | $CMP 74LS20 712 | D Dual 4-input NAND 713 | K TTL Nand4 714 | F http://www.ti.com/lit/gpn/sn74LS20 715 | $ENDCMP 716 | # 717 | $CMP 74LS21 718 | D Dual 4-input AND 719 | K TTL And4 720 | F http://www.ti.com/lit/gpn/sn74LS21 721 | $ENDCMP 722 | # 723 | $CMP 74LS22 724 | D Dual 4-input NAND Open Collector 725 | K TTL Nand4 OpenColl 726 | F http://www.ti.com/lit/gpn/sn74LS22 727 | $ENDCMP 728 | # 729 | $CMP 74LS221 730 | D Dual Monostable 731 | K TTL Monostable 732 | F http://www.ti.com/lit/gpn/sn74LS221 733 | $ENDCMP 734 | # 735 | $CMP 74LS240 736 | D 8-bit BUS Buffer (Inverter) 3-State outputs 737 | K TTL Buffer BUS 3State 738 | F http://www.ti.com/lit/gpn/sn74LS240 739 | $ENDCMP 740 | # 741 | $CMP 74LS241 742 | D 8-bit Bus Buffer 3-State outputs 743 | K TTL Buffer BUS 3State 744 | F http://www.ti.com/lit/gpn/sn74LS241 745 | $ENDCMP 746 | # 747 | $CMP 74LS242 748 | D quad bus transceiver, inverting 3-state outputs 749 | K bus 3state 750 | F http://www.ti.com/lit/gpn/sn74LS242 751 | $ENDCMP 752 | # 753 | $CMP 74LS243 754 | D 4-bit Bus Tranceiver 755 | K TTL Buffer 3State BUS BIDI 756 | F http://www.ti.com/lit/gpn/sn74LS243 757 | $ENDCMP 758 | # 759 | $CMP 74LS244 760 | D 8-bit Bus Buffer 3-State outputs 761 | K TTL Buffer BUS 3State 762 | F http://www.ti.com/lit/gpn/sn74LS244 763 | $ENDCMP 764 | # 765 | $CMP 74LS245 766 | D Octal BUS Transceivers, 3-State outputs 767 | K TTL BUS 3State 768 | F http://www.ti.com/lit/gpn/sn74LS245 769 | $ENDCMP 770 | # 771 | $CMP 74LS246 772 | D BCD to 7-segment Decoder Open Collector active Low 773 | K TTL DECOD 774 | F http://www.ti.com/lit/gpn/sn74LS246 775 | $ENDCMP 776 | # 777 | $CMP 74LS247 778 | D BCD to 7 segments Decoder Open Collector active Low 779 | K TTL DECOD 780 | F http://www.ti.com/lit/gpn/sn74LS247 781 | $ENDCMP 782 | # 783 | $CMP 74LS248 784 | D BCD to 7-segment Decoder, Active High 785 | K TTL DECOD 786 | F http://www.ti.com/lit/gpn/sn74LS248 787 | $ENDCMP 788 | # 789 | $CMP 74LS249 790 | D BCD to 7-segment Decoder, Open collector, Active High 791 | K TTL DECOD OpenCol 792 | F http://www.ti.com/lit/gpn/sn74LS249 793 | $ENDCMP 794 | # 795 | $CMP 74LS251 796 | D Multiplexer 8 to 1, 3-state Outputs 797 | K TTL MUX MUX8 3State 798 | F http://www.ti.com/lit/gpn/sn74LS251 799 | $ENDCMP 800 | # 801 | $CMP 74LS253 802 | D Dual Multiplexer 4 to 1, 3-State Outputs 803 | K TTL MUX MUX4 3State 804 | F http://www.ti.com/lit/gpn/sn74LS253 805 | $ENDCMP 806 | # 807 | $CMP 74LS256 808 | D dual 4-bit addressable latch 809 | K latch 810 | F http://www.ti.com/lit/gpn/sn74LS256 811 | $ENDCMP 812 | # 813 | $CMP 74LS257 814 | D Quad 2 to 1 Multiplexer 815 | K TTL MUX MUX2 816 | F http://www.ti.com/lit/gpn/sn74LS257 817 | $ENDCMP 818 | # 819 | $CMP 74LS258 820 | D Quad 2 to 1 Multiplexer, inverting 821 | K TTL MUX MUX2 822 | F http://www.ti.com/lit/gpn/sn74LS258 823 | $ENDCMP 824 | # 825 | $CMP 74LS259 826 | D 8-bit addressable latch 827 | K TTL REG DFF 828 | F http://www.ti.com/lit/gpn/sn74LS259 829 | $ENDCMP 830 | # 831 | $CMP 74LS26 832 | D Quad 2-input NAND Open collector 833 | K TTL Nand2 OpenCol 834 | F http://www.ti.com/lit/gpn/sn74LS26 835 | $ENDCMP 836 | # 837 | $CMP 74LS27 838 | D Triple 3-input NOR 839 | K TTL Nor3 840 | F http://www.ti.com/lit/gpn/sn74LS27 841 | $ENDCMP 842 | # 843 | $CMP 74LS273 844 | D 8-bit D Flip-Flop, reset 845 | K TTL DFF DFF8 846 | F http://www.ti.com/lit/gpn/sn74LS273 847 | $ENDCMP 848 | # 849 | $CMP 74LS28 850 | D quad 2-input NOR buffer NRND 851 | K TTL Nor2 Buffer 852 | F http://eeshop.unl.edu/pdf/74ls28.pdf 853 | $ENDCMP 854 | # 855 | $CMP 74LS280 856 | D Parity Generator/Checker 857 | K TTL ALU Arith 858 | F http://www.ti.com/lit/gpn/sn74LS280 859 | $ENDCMP 860 | # 861 | $CMP 74LS283 862 | D 4-bit full Adder 863 | K TTL ADD Arith ALU 864 | F http://www.ti.com/lit/gpn/sn74LS283 865 | $ENDCMP 866 | # 867 | $CMP 74LS290 868 | D 4-bit BCD counter 869 | K TTL CNT CNT4 870 | F http://www.ti.com/lit/gpn/sn74LS290 871 | $ENDCMP 872 | # 873 | $CMP 74LS293 874 | D 4-bit binary counter 875 | K TTL CNT CNT4 876 | F http://www.ti.com/lit/gpn/sn74LS293 877 | $ENDCMP 878 | # 879 | $CMP 74LS295 880 | D 4-bit bidirectional register, 3-state outputs 881 | K register 882 | F http://www.ti.com/lit/gpn/sn74LS295 883 | $ENDCMP 884 | # 885 | $CMP 74LS298 886 | D Quad 2 to 1 multiplexer with storage 887 | K TTL MUX MUX2 888 | F http://www.ti.com/lit/gpn/sn74LS298 889 | $ENDCMP 890 | # 891 | $CMP 74LS299 892 | D 8-bit Universal shift/storage Register 893 | K TTL REG SR SR8 894 | F http://www.ti.com/lit/gpn/sn74LS299 895 | $ENDCMP 896 | # 897 | $CMP 74LS30 898 | D 8-input NAND 899 | K TTL Nand8 900 | F http://www.ti.com/lit/gpn/sn74LS30 901 | $ENDCMP 902 | # 903 | $CMP 74LS32 904 | D Quad 2-input OR 905 | K TTL Or2 906 | F http://www.ti.com/lit/gpn/sn74LS32 907 | $ENDCMP 908 | # 909 | $CMP 74LS322 910 | D 8-bit shift register, sign extend, 3-state outputs 911 | K register 912 | F http://www.ti.com/lit/gpn/sn74LS322 913 | $ENDCMP 914 | # 915 | $CMP 74LS323 916 | D 8-bit Universal Shift/Storage Register 917 | K TTL REG SR SR8 918 | F http://www.ti.com/lit/gpn/sn74LS323 919 | $ENDCMP 920 | # 921 | $CMP 74LS33 922 | D Quad 2-input NOR, Open collector 923 | K TTL Nor2 OpenColl 924 | F http://www.ti.com/lit/gpn/sn74LS33 925 | $ENDCMP 926 | # 927 | $CMP 74LS348 928 | D 8 to 3 lines Priority Encoder 929 | K TTL ENCOD Arith 930 | F http://www.ti.com/lit/gpn/sn74LS348 931 | $ENDCMP 932 | # 933 | $CMP 74LS352 934 | D Dual 4 to 1 line Multiplexer 935 | K TTL Mux MUX4 936 | F http://www.ti.com/lit/gpn/sn74LS352 937 | $ENDCMP 938 | # 939 | $CMP 74LS353 940 | D Dual 4 to 1 line Multiplexer, inverter 941 | K TTL MUX MUX2 942 | F http://www.ti.com/lit/gpn/sn74LS353 943 | $ENDCMP 944 | # 945 | $CMP 74LS365 946 | D Hex Bus Driver, 3-State Outputs 947 | K TTL Buffer BUS 3State 948 | F http://www.ti.com/lit/gpn/sn74LS365 949 | $ENDCMP 950 | # 951 | $CMP 74LS366 952 | D Hex Bus Driver inverter, 3-state outputs 953 | K TTL Buffer BUS 3State 954 | F http://www.ti.com/lit/gpn/sn74LS366 955 | $ENDCMP 956 | # 957 | $CMP 74LS367 958 | D Hex Bus Driver 3-state outputs 959 | K TTL Buffer BUS 3State 960 | F http://www.ti.com/lit/gpn/sn74LS367 961 | $ENDCMP 962 | # 963 | $CMP 74LS368 964 | D Hex Bus Driver inverter, 3-state outputs 965 | K TTL Buffer BUS 3State 966 | F http://www.ti.com/lit/gpn/sn74LS368 967 | $ENDCMP 968 | # 969 | $CMP 74LS37 970 | D quad 2-input NAND buffer 971 | K TTL nand 2-input buffer 972 | F http://www.ti.com/lit/gpn/sn74ls37 973 | $ENDCMP 974 | # 975 | $CMP 74LS373 976 | D 8-bit Latch, 3-state outputs 977 | K TTL REG DFF DFF8 LATCH 978 | F http://www.ti.com/lit/gpn/sn74LS373 979 | $ENDCMP 980 | # 981 | $CMP 74LS374 982 | D 8-bit Register, 3-state outputs 983 | K TTL DFF DFF8 REG 3State 984 | F http://www.ti.com/lit/gpn/sn74LS374 985 | $ENDCMP 986 | # 987 | $CMP 74LS375 988 | D 4-bit Latch 989 | K TTL DFF DFF4 Latch 990 | F http://www.ti.com/lit/gpn/sn74LS375 991 | $ENDCMP 992 | # 993 | $CMP 74LS377 994 | D 8-bit Register 995 | K TTL REG DFF DFF8 996 | F http://www.ti.com/lit/gpn/sn74LS377 997 | $ENDCMP 998 | # 999 | $CMP 74LS378 1000 | D 6-bit Register 1001 | K TTL REG DFF DFF6 1002 | F http://www.ti.com/lit/gpn/sn74LS378 1003 | $ENDCMP 1004 | # 1005 | $CMP 74LS379 1006 | D 4-bit Register 1007 | K TTL REG DFF DFF4 1008 | F http://www.ti.com/lit/gpn/sn74LS379 1009 | $ENDCMP 1010 | # 1011 | $CMP 74LS38 1012 | D Quad Buffer 2-input NAND Open collector 1013 | K TTL Nand2 OpenCol Buffer 1014 | F http://www.ti.com/lit/gpn/sn74LS38 1015 | $ENDCMP 1016 | # 1017 | $CMP 74LS385 1018 | D Quad serial Adder 1019 | K TTL ADD Arith ALU 1020 | F http://www.ti.com/lit/gpn/sn74LS385 1021 | $ENDCMP 1022 | # 1023 | $CMP 74LS386 1024 | D Quad 2-input XOR 1025 | K TTL XOR2 1026 | F http://www.ti.com/lit/gpn/sn74LS386 1027 | $ENDCMP 1028 | # 1029 | $CMP 74LS390 1030 | D Dual BCD 4-bit counter 1031 | K TTL CNT CNT4 1032 | F http://www.ti.com/lit/gpn/sn74LS390 1033 | $ENDCMP 1034 | # 1035 | $CMP 74LS393 1036 | D Dual BCD 4-bit counter 1037 | K TTL CNT CNT4 1038 | F 74xx\74LS393.pdf 1039 | $ENDCMP 1040 | # 1041 | $CMP 74LS395 1042 | D 4-bit universal shift register, 3-state outputs 1043 | K TTL SR SR4 REG 3State 1044 | F http://www.ti.com/lit/gpn/sn74LS395 1045 | $ENDCMP 1046 | # 1047 | $CMP 74LS398 1048 | D Quad 2 to 1 line Multiplexer, 3-state outputs 1049 | K TTL MUX MUX2 3State 1050 | F http://www.ti.com/lit/gpn/sn74LS398 1051 | $ENDCMP 1052 | # 1053 | $CMP 74LS399 1054 | D Quad 2 to 1 line multiplexer with storage 1055 | K TTL MUX MUX2 1056 | F http://www.ti.com/lit/gpn/sn74LS399 1057 | $ENDCMP 1058 | # 1059 | $CMP 74LS40 1060 | D Dual 4-input NAND 1061 | K TTL Nand4 1062 | F http://www.ti.com/lit/gpn/sn74LS40 1063 | $ENDCMP 1064 | # 1065 | $CMP 74LS42 1066 | D 4 to 10 line Decoder 1067 | K TTL DECOD DECOD10 1068 | F http://www.ti.com/lit/gpn/sn74LS42 1069 | $ENDCMP 1070 | # 1071 | $CMP 74LS46 1072 | D BCD to 7-segment Driver, Open Collector, 15V outputs 1073 | K TTL DECOD DECOD7 OpenCol 1074 | F http://www.ti.com/lit/gpn/sn74LS46 1075 | $ENDCMP 1076 | # 1077 | $CMP 74LS47 1078 | D BCD to 7-segment Driver, Open Collector, 30V outputs 1079 | K TTL DECOD DECOD7 OpenCol 1080 | F http://www.ti.com/lit/gpn/sn74LS47 1081 | $ENDCMP 1082 | # 1083 | $CMP 74LS48 1084 | D BCD to 7-segment Decoder/driver, Active High outputs 1085 | K TTL DECOD DECOD7 1086 | F http://www.ti.com/lit/gpn/sn74LS48 1087 | $ENDCMP 1088 | # 1089 | $CMP 74LS49 1090 | D BCD to 7-segment decoder/driver, Open collector 1091 | K TTL DECOD DECOD7 OpenCol 1092 | F http://www.ti.com/lit/gpn/sn74ls47 1093 | $ENDCMP 1094 | # 1095 | $CMP 74LS51 1096 | D Dual 3- and 2-input AND-NOR ( S = /(AB[C] + DE[F]) ) 1097 | K TTL ANDNOR 1098 | F http://www.ti.com/lit/ds/symlink/sn74ls51.pdf 1099 | $ENDCMP 1100 | # 1101 | $CMP 74LS54 1102 | D And-Nor (S = /(AB + CD + EF + GH) ) 1103 | K TTL ANDNOR 1104 | F http://www.ti.com/lit/gpn/sn74LS54 1105 | $ENDCMP 1106 | # 1107 | $CMP 74LS540 1108 | D 8-bit Buffer/Line driver Inverter, 3-state outputs 1109 | K BUFFER BUS TTL 3State 1110 | F http://www.ti.com/lit/gpn/sn74LS540 1111 | $ENDCMP 1112 | # 1113 | $CMP 74LS541 1114 | D 8-bit Buffer/Line Driver 3-state outputs 1115 | K TTL BUFFER 3State BUS 1116 | F http://www.ti.com/lit/gpn/sn74LS541 1117 | $ENDCMP 1118 | # 1119 | $CMP 74LS55 1120 | D AND-NOR ( S = / (ABCD + EFGH) ) 1121 | K TTL ANDNOR 1122 | F http://www.ti.com/lit/gpn/sn74LS55 1123 | $ENDCMP 1124 | # 1125 | $CMP 74LS573 1126 | D 8-bit Latch 3-state outputs 1127 | K TTL DFF DFF8 LATCH 3State 1128 | F 74xx/74hc573.pdf 1129 | $ENDCMP 1130 | # 1131 | $CMP 74LS574 1132 | D 8-bit Register, 3-state outputs 1133 | K TTL REG DFF DFF8 3State 1134 | F http://www.ti.com/lit/gpn/sn74LS574 1135 | $ENDCMP 1136 | # 1137 | $CMP 74LS590 1138 | D 8-bit Binary Counter with Output Register 3-State Outputs, DIP-16/SOIC-16/SOIC-16W 1139 | K TTL Counter 3State 1140 | F http://www.ti.com/lit/gpn/sn74ls590 1141 | $ENDCMP 1142 | # 1143 | $CMP 74LS595 1144 | D 8-bit serial in/out Shift Register 3-State Outputs 1145 | K TTL SR 3State 1146 | F http://www.ti.com/lit/gpn/sn74ls595 1147 | $ENDCMP 1148 | # 1149 | $CMP 74LS596 1150 | D 8-bit serial in/out Shift Register Open Collector outputs 1151 | K HCMOS SR OpenCollector 1152 | F http://www.ti.com/lit/gpn/sn74ls596 1153 | $ENDCMP 1154 | # 1155 | $CMP 74LS629 1156 | D dual voltage-controlled oscillator, enable control, range control 1157 | K VCO 1158 | F http://www.ti.com/lit/gpn/sn74LS629 1159 | $ENDCMP 1160 | # 1161 | $CMP 74LS670 1162 | D 4 x 4 Register Files 3-State Outputs 1163 | K TTL Register 3State 1164 | F http://www.ti.com/lit/gpn/sn74LS670 1165 | $ENDCMP 1166 | # 1167 | $CMP 74LS688 1168 | D 8-bit Comparator 1169 | K TTL DECOD Arith 1170 | F http://www.ti.com/lit/gpn/sn74LS688 1171 | $ENDCMP 1172 | # 1173 | $CMP 74LS73 1174 | D Dual JK Flip-Flop, reset 1175 | K TTL JK JKFF 1176 | F http://www.ti.com/lit/gpn/sn74LS73 1177 | $ENDCMP 1178 | # 1179 | $CMP 74LS74 1180 | D Dual D Flip-flop, Set & Reset 1181 | K TTL DFF 1182 | F 74xx/74hc_hct74.pdf 1183 | $ENDCMP 1184 | # 1185 | $CMP 74LS75 1186 | D 4-bit Latch 1187 | K TTL DFF Latch 1188 | F http://www.ti.com/lit/gpn/sn74LS75 1189 | $ENDCMP 1190 | # 1191 | $CMP 74LS76 1192 | D Dual JK Flip-flop, Set & Reset 1193 | K TTL JK JKFF 1194 | F http://www.ti.com/lit/gpn/sn74LS76 1195 | $ENDCMP 1196 | # 1197 | $CMP 74LS77 1198 | D 4-bit Latch 1199 | K TTL DFF Latch 1200 | F http://www.ti.com/lit/gpn/sn74LS77 1201 | $ENDCMP 1202 | # 1203 | $CMP 74LS78 1204 | D Dual JK Flip-flop, Set, Common clock & reset 1205 | K TTL JK JKFF 1206 | F http://www.ti.com/lit/gpn/sn74LS78 1207 | $ENDCMP 1208 | # 1209 | $CMP 74LS83 1210 | D 4-bit Full Adder 1211 | K TTL ADD ARITH ALU 1212 | F http://www.ti.com/lit/gpn/sn74LS83 1213 | $ENDCMP 1214 | # 1215 | $CMP 74LS85 1216 | D 4-bit Comparator 1217 | K TTL COMP ARITH 1218 | F http://www.ti.com/lit/gpn/sn74LS85 1219 | $ENDCMP 1220 | # 1221 | $CMP 74LS86 1222 | D Quad 2-input XOR 1223 | K TTL XOR2 1224 | F 74xx/74ls86.pdf 1225 | $ENDCMP 1226 | # 1227 | $CMP 74LS90 1228 | D BCD Counter ( div 2 & div 5 ) 1229 | K TTL CNT CNT4 1230 | F http://www.ti.com/lit/gpn/sn74LS90 1231 | $ENDCMP 1232 | # 1233 | $CMP 74LS91 1234 | D 8-bit Serial Register 1235 | K TTL SR SR8 1236 | F http://www.ti.com/lit/gpn/sn74LS91 1237 | $ENDCMP 1238 | # 1239 | $CMP 74LS92 1240 | D Divide by 12 counter 1241 | K TTL CNT CNT4 1242 | F http://www.ti.com/lit/gpn/sn74LS92 1243 | $ENDCMP 1244 | # 1245 | $CMP 74LS93 1246 | D Divide by 2 & 8 counter 1247 | K TTL CNT CNT4 1248 | F http://www.ti.com/lit/gpn/sn74LS93 1249 | $ENDCMP 1250 | # 1251 | $CMP 74LS95 1252 | D Shift Register 5-bit (in/out) 1253 | K TTL SR SR4 1254 | F http://www.ti.com/lit/gpn/sn74LS95 1255 | $ENDCMP 1256 | # 1257 | $CMP 74LV14 1258 | D Hex Inverter 1259 | K TTL not inv 1260 | F http://www.ti.com/lit/gpn/sn74LV14 1261 | $ENDCMP 1262 | # 1263 | $CMP 74LV8154 1264 | D Dual 16-bit binary counter 1265 | K counter binary 1266 | F http://www.ti.com/lit/ds/symlink/sn74lv8154.pdf 1267 | $ENDCMP 1268 | # 1269 | $CMP 74LVC125 1270 | D Quad buffer 3-State outputs 1271 | K TTL buffer 3State 1272 | F http://www.ti.com/lit/gpn/sn74LVC125 1273 | $ENDCMP 1274 | # 1275 | $CMP CD74HC4067M 1276 | D High-Speed CMOS Logic 16-Channel Analog Multiplexer/Demultiplexer, SOIC-24 1277 | K multiplexer demultiplexer mux demux 1278 | F http://www.ti.com/lit/ds/symlink/cd74hc4067.pdf 1279 | $ENDCMP 1280 | # 1281 | $CMP CD74HC4067SM 1282 | D High-Speed CMOS Logic 16-Channel Analog Multiplexer/Demultiplexer, SSOP-24 1283 | K multiplexer demultiplexer mux demux 1284 | F http://www.ti.com/lit/ds/symlink/cd74hc4067.pdf 1285 | $ENDCMP 1286 | # 1287 | $CMP MM74C923 1288 | D 20-key encoder 1289 | K encoder 1290 | F http://www.ti.com/lit/gpn/snMM74C923 1291 | $ENDCMP 1292 | # 1293 | $CMP SN74AVC16827DGGR 1294 | D 20-Bit Buffer/Driver With 3-State Outputs 1295 | K Buffer Driver 3-State 1296 | F http://www.ti.com/lit/ds/symlink/sn74avc16827.pdf 1297 | $ENDCMP 1298 | # 1299 | $CMP SN74LS07 1300 | D Hex Buffers and Drivers With Open Collector High Voltage Outputs 1301 | K TTL hex buffer OpenCol 1302 | F www.ti.com/lit/ds/symlink/sn74ls07.pdf 1303 | $ENDCMP 1304 | # 1305 | $CMP SN74LS07N 1306 | D Hex Buffers and Drivers With Open Collector High Voltage Outputs 1307 | K TTL hex buffer OpenCol 1308 | F www.ti.com/lit/ds/symlink/sn74ls07.pdf 1309 | $ENDCMP 1310 | # 1311 | #End Doc Library 1312 | -------------------------------------------------------------------------------- /kicad/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all clean sim_counter 2 | 3 | all: boneless.net 4 | 5 | %.json: ../benchmarks/%.v ../74ac.lib ../74_models.v ../74_adder.v ../74_dffe.v ../74_mux.v ../synth_74.ys 6 | yosys -q -s ../synth_74.ys -p "write_json $@" $< 7 | 8 | %.net: %.json generate_netlist.py parts.py 9 | python3 generate_netlist.py $< 10 | 11 | clean: 12 | rm -f *.net *.json *.erc *.log 13 | -------------------------------------------------------------------------------- /kicad/generate_netlist.py: -------------------------------------------------------------------------------- 1 | import skidl 2 | import json 3 | import sys 4 | import os.path 5 | import pprint 6 | import pdb 7 | 8 | from parts import * 9 | 10 | def get_toplevel(data): 11 | top = None 12 | for mod in data['modules'].values(): 13 | if 'top' in mod['attributes']: 14 | top = mod 15 | break 16 | return top 17 | 18 | 19 | def create_nets(top): 20 | nets = {} 21 | nets['0']=GND 22 | nets['1']=VCC 23 | for name, net in top['netnames'].items(): 24 | for bit in net['bits']: 25 | if not bit in nets: 26 | net = skidl.Net(name) 27 | nets[bit] = net 28 | else: 29 | net = nets[bit] 30 | # suppress ERC warnings about unconnected pins 31 | if name in top['ports'] and top['ports'][name]['direction']=='input': 32 | net.drive = skidl.POWER 33 | 34 | return nets 35 | 36 | def group_by(key, data): 37 | groups = {} 38 | for val in data: 39 | groups.setdefault(key(val), []).append(val) 40 | return groups 41 | 42 | def make_abc(fnew, mapping, instances, nets, base=0): 43 | new_cap() 44 | chip = fnew() 45 | idx = base 46 | for inst in instances: 47 | if not chip[next(iter(mapping)).format(idx)]: 48 | new_cap() 49 | chip = fnew() 50 | idx = base 51 | 52 | for ch, nl in mapping.items(): 53 | try: 54 | chip[ch.format(idx)] += nets[inst['connections'][nl][0]] 55 | except TypeError: 56 | print("Pin", ch.format(idx), "not found") 57 | print(chip) 58 | raise 59 | 60 | idx+=1 61 | 62 | # suppress ERC warnings about unconnected pins 63 | while chip[next(iter(mapping)).format(idx)]: 64 | for ch, nl in mapping.items(): 65 | if "{}" in ch: #only numbered pins 66 | chip[ch.format(idx)] += NC 67 | idx+=1 68 | 69 | def make_techmap(fnew, mapping, instances, nets, base=0): 70 | for inst in instances: 71 | new_cap() 72 | chip = fnew() 73 | for ch, nl in mapping.items(): 74 | for i, a in enumerate(inst['connections'][nl]): 75 | chip[ch.format(i+base)] += nets[a] 76 | 77 | def pin_getter(*args): 78 | return lambda chip: tuple(chip['connections'][arg][0] for arg in args) 79 | 80 | def create_chips(chip_types, nets): 81 | for typ, chips in chip_types.items(): 82 | if typ == '\\74AC16374_16x1DFF': 83 | mapping = {"D{}":"D", "O{}":"Q", "Cp": "CLK"} 84 | clocks = group_by(pin_getter("CLK"), chips) 85 | for instances in clocks.values(): 86 | make_abc(new_74374, mapping, instances, nets) 87 | elif typ == '\\74AC377_8x1DFFE': 88 | mapping = {"D{}":"D", "Q{}":"Q", "~E": "CE", "CP": "CP"} 89 | clocks = group_by(pin_getter("CP", "CE"), chips) 90 | for instances in clocks.values(): 91 | make_abc(new_74377, mapping, instances, nets) 92 | elif typ == '\\74AC273_8x1DFFR': 93 | mapping = {"D{}":"D", "Q{}":"Q", "Cp": "CLK", "~Mr": "C"} 94 | clocks = group_by(pin_getter("CLK", "C"), chips) 95 | for instances in clocks.values(): 96 | make_abc(new_74273, mapping, instances, nets) 97 | elif typ == '\\74AC11074_2x1DFFSR': 98 | mapping = {"D{}":"D", "Q{}":"Q", "C{}": "CLK", "~R{}": "C", "~S": "P"} 99 | make_abc(new_7474, mapping, chips, nets, 1) 100 | elif typ == '\\74AC11257_4x1MUX2': 101 | mapping = {"{}A": "A", "{}B": "B", "{}Y": "Y", "S": "S"} 102 | select = group_by(pin_getter("S"), chips) 103 | for instances in select.values(): 104 | make_abc(new_74257, mapping, instances, nets, 1) 105 | elif typ == '\\74AC158_4x1MUXI2': 106 | mapping = {"{}A": "A", "{}B": "B", "{}Y": "Y", "S": "S"} 107 | select = group_by(pin_getter("S"), chips) 108 | for instances in select.values(): 109 | make_abc(new_74158, mapping, instances, nets, 1) 110 | elif typ == '\\74AC153_2x1MUX4': 111 | mapping = {"{}A": "A", "{}B": "B", "{}C": "C", "{}D": "D", 112 | "{}Y": "Y", "S0": "S", "S1": "T"} 113 | select = group_by(pin_getter("S", "T"), chips) 114 | for instances in select.values(): 115 | make_abc(new_74153, mapping, instances, nets, 1) 116 | elif typ == '\\74AC151_1x1MUX8': 117 | mapping = {"I0": "A", "I1": "B", "I2": "C", "I3": "D", 118 | "I4": "E", "I5": "F", "I6": "G", "I7": "H", 119 | "Z": "Y", "S0": "S", "S1": "T", "S2": "U"} 120 | select = group_by(pin_getter("S", "T", "U"), chips) 121 | for instances in select.values(): 122 | #ABC but only one mux per chip 123 | make_techmap(new_74151, mapping, instances, nets) 124 | elif typ == '\\74AC151_1x1MUXI8': 125 | mapping = {"I0": "A", "I1": "B", "I2": "C", "I3": "D", 126 | "I4": "E", "I5": "F", "I6": "G", "I7": "H", 127 | "~Z": "Y", "S0": "S", "S1": "T", "S2": "U"} 128 | select = group_by(pin_getter("S", "T", "U"), chips) 129 | for instances in select.values(): 130 | #ABC but only one mux per chip 131 | make_techmap(new_74151, mapping, instances, nets) 132 | elif typ == '\\74AC11086_4x1XOR2': 133 | mapping = {"{}A": "A", "{}B": "B", "{}Y": "Y"} 134 | make_abc(new_7486, mapping, chips, nets, 1) 135 | elif typ == '\\74AC11004_6x1NOT': 136 | mapping = {"{}A": "A", "{}Y": "Y"} 137 | make_abc(new_7404, mapping, chips, nets, 1) 138 | elif typ == '\\74AC02_4x1NOR2': 139 | mapping = {"{}A": "A", "{}B": "B", "{}Y": "Y"} 140 | make_abc(new_7402, mapping, chips, nets, 1) 141 | elif typ == '\\74AC11_3x1AND3': 142 | mapping = {"{}A": "A", "{}B": "B", "{}C": "C", "{}Y": "Y"} 143 | make_abc(new_7411, mapping, chips, nets, 1) 144 | elif typ == '\\74AC10_3x1NAND3': 145 | mapping = {"{}A": "A", "{}B": "B", "{}C": "C", "{}Y": "Y"} 146 | make_abc(new_7410, mapping, chips, nets, 1) 147 | elif typ == '\\74AC20_2x1NAND4': 148 | mapping = {"{}A": "A", "{}B": "B", "{}C": "C", "{}D": "D", "{}Y": "Y"} 149 | make_abc(new_7420, mapping, chips, nets, 1) 150 | elif typ == '\\74AC11032_4x1OR2': 151 | mapping = {"{}A": "A", "{}B": "B", "{}Y": "Y"} 152 | make_abc(new_7432, mapping, chips, nets, 1) 153 | elif typ == '\\74AC11008_4x1AND2': 154 | mapping = {"{}A": "A", "{}B": "B", "{}Y": "Y"} 155 | make_abc(new_7408, mapping, chips, nets, 1) 156 | elif typ == '\\74AC11000_4x1NAND2': 157 | mapping = {"{}A": "A", "{}B": "B", "{}Y": "Y"} 158 | make_abc(new_7400, mapping, chips, nets, 1) 159 | elif typ == '\\74AC11244_8x1BUF': 160 | mapping = {"A{}": "A", "Y{}": "Y"} 161 | make_abc(new_74244, mapping, chips, nets, 1) 162 | elif typ == '\\74AC283_1x1ADD4': 163 | mapping = {"C0": "CI", "C4": "CO", "A{}": "A", "B{}": "B", "S{}": "S"} 164 | make_techmap(new_74283, mapping, chips, nets, 1) 165 | elif typ == '\\74HC85_1x1CMP4': 166 | mapping = {"A{}": "A", "B{}": "B", 167 | "Ia=b": "Ei", "Oa=b": "Eo", 168 | "Ia>b": "Gi", "Oa>b": "Go", 169 | "Ia