diff --git a/techlibs/common/blackbox.sed b/techlibs/common/blackbox.sed index 21693ecdd..db8900344 100644 --- a/techlibs/common/blackbox.sed +++ b/techlibs/common/blackbox.sed @@ -1,4 +1,5 @@ #!/bin/sed -r -/^(wire|assign|reg|event)/ d; -/^(genvar|generate|always|initial)/,/^end/ d; +/^(wire|assign|reg|event|integer|localparam|\/\/|[\/ ]\*| *$|`)/ d; +/^(genvar|generate|always|initial|task|function)/,/^end/ d; +/^endmodule/ s/$/\n/; s/ reg / /; diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 1b67f3257..da745b5e0 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -795,87 +795,89 @@ endmodule // -------------------------------------------------------- module \$macc (A, B, Y); - parameter A_WIDTH = 0; - parameter B_WIDTH = 0; - parameter Y_WIDTH = 0; - parameter CONFIG = 4'b0000; - parameter CONFIG_WIDTH = 4; - input [A_WIDTH-1:0] A; - input [B_WIDTH-1:0] B; - output reg [Y_WIDTH-1:0] Y; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; +parameter CONFIG = 4'b0000; +parameter CONFIG_WIDTH = 4; - localparam integer num_bits = CONFIG[3:0]; - localparam integer num_ports = (CONFIG_WIDTH-4) / (2 + 2*num_bits); - localparam integer num_abits = $clog2(A_WIDTH) > 0 ? $clog2(A_WIDTH) : 1; +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output reg [Y_WIDTH-1:0] Y; - function [2*num_ports*num_abits-1:0] get_port_offsets; - input [CONFIG_WIDTH-1:0] cfg; - integer i, cursor; - begin - cursor = 0; - get_port_offsets = 0; - for (i = 0; i < num_ports; i = i+1) begin - get_port_offsets[(2*i + 0)*num_abits +: num_abits] = cursor; - cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 +: num_bits]; - get_port_offsets[(2*i + 1)*num_abits +: num_abits] = cursor; - cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]; - end - end - endfunction +localparam integer num_bits = CONFIG[3:0]; +localparam integer num_ports = (CONFIG_WIDTH-4) / (2 + 2*num_bits); +localparam integer num_abits = $clog2(A_WIDTH) > 0 ? $clog2(A_WIDTH) : 1; - localparam [2*num_ports*num_abits-1:0] port_offsets = get_port_offsets(CONFIG); - - `define PORT_IS_SIGNED (0 + CONFIG[4 + i*(2 + 2*num_bits)]) - `define PORT_DO_SUBTRACT (0 + CONFIG[4 + i*(2 + 2*num_bits) + 1]) - `define PORT_SIZE_A (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 +: num_bits]) - `define PORT_SIZE_B (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]) - `define PORT_OFFSET_A (0 + port_offsets[2*i*num_abits +: num_abits]) - `define PORT_OFFSET_B (0 + port_offsets[2*i*num_abits + num_abits +: num_abits]) - - integer i, j; - reg [Y_WIDTH-1:0] tmp_a, tmp_b; - - always @* begin - Y = 0; - for (i = 0; i < num_ports; i = i+1) - begin - tmp_a = 0; - tmp_b = 0; - - for (j = 0; j < `PORT_SIZE_A; j = j+1) - tmp_a[j] = A[`PORT_OFFSET_A + j]; - - if (`PORT_IS_SIGNED && `PORT_SIZE_A > 0) - for (j = `PORT_SIZE_A; j < Y_WIDTH; j = j+1) - tmp_a[j] = tmp_a[`PORT_SIZE_A-1]; - - for (j = 0; j < `PORT_SIZE_B; j = j+1) - tmp_b[j] = A[`PORT_OFFSET_B + j]; - - if (`PORT_IS_SIGNED && `PORT_SIZE_B > 0) - for (j = `PORT_SIZE_B; j < Y_WIDTH; j = j+1) - tmp_b[j] = tmp_b[`PORT_SIZE_B-1]; - - if (`PORT_SIZE_B > 0) - tmp_a = tmp_a * tmp_b; - - if (`PORT_DO_SUBTRACT) - Y = Y - tmp_a; - else - Y = Y + tmp_a; - end - for (i = 0; i < B_WIDTH; i = i+1) begin - Y = Y + B[i]; +function [2*num_ports*num_abits-1:0] get_port_offsets; + input [CONFIG_WIDTH-1:0] cfg; + integer i, cursor; + begin + cursor = 0; + get_port_offsets = 0; + for (i = 0; i < num_ports; i = i+1) begin + get_port_offsets[(2*i + 0)*num_abits +: num_abits] = cursor; + cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 +: num_bits]; + get_port_offsets[(2*i + 1)*num_abits +: num_abits] = cursor; + cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]; end end +endfunction + +localparam [2*num_ports*num_abits-1:0] port_offsets = get_port_offsets(CONFIG); + +`define PORT_IS_SIGNED (0 + CONFIG[4 + i*(2 + 2*num_bits)]) +`define PORT_DO_SUBTRACT (0 + CONFIG[4 + i*(2 + 2*num_bits) + 1]) +`define PORT_SIZE_A (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 +: num_bits]) +`define PORT_SIZE_B (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]) +`define PORT_OFFSET_A (0 + port_offsets[2*i*num_abits +: num_abits]) +`define PORT_OFFSET_B (0 + port_offsets[2*i*num_abits + num_abits +: num_abits]) + +integer i, j; +reg [Y_WIDTH-1:0] tmp_a, tmp_b; + +always @* begin + Y = 0; + for (i = 0; i < num_ports; i = i+1) + begin + tmp_a = 0; + tmp_b = 0; + + for (j = 0; j < `PORT_SIZE_A; j = j+1) + tmp_a[j] = A[`PORT_OFFSET_A + j]; + + if (`PORT_IS_SIGNED && `PORT_SIZE_A > 0) + for (j = `PORT_SIZE_A; j < Y_WIDTH; j = j+1) + tmp_a[j] = tmp_a[`PORT_SIZE_A-1]; + + for (j = 0; j < `PORT_SIZE_B; j = j+1) + tmp_b[j] = A[`PORT_OFFSET_B + j]; + + if (`PORT_IS_SIGNED && `PORT_SIZE_B > 0) + for (j = `PORT_SIZE_B; j < Y_WIDTH; j = j+1) + tmp_b[j] = tmp_b[`PORT_SIZE_B-1]; + + if (`PORT_SIZE_B > 0) + tmp_a = tmp_a * tmp_b; + + if (`PORT_DO_SUBTRACT) + Y = Y - tmp_a; + else + Y = Y + tmp_a; + end + for (i = 0; i < B_WIDTH; i = i+1) begin + Y = Y + B[i]; + end +end + +`undef PORT_IS_SIGNED +`undef PORT_DO_SUBTRACT +`undef PORT_SIZE_A +`undef PORT_SIZE_B +`undef PORT_OFFSET_A +`undef PORT_OFFSET_B - `undef PORT_IS_SIGNED - `undef PORT_DO_SUBTRACT - `undef PORT_SIZE_A - `undef PORT_SIZE_B - `undef PORT_OFFSET_A - `undef PORT_OFFSET_B endmodule // --------------------------------------------------------