55 lines
1.7 KiB
Verilog
55 lines
1.7 KiB
Verilog
module sparse_vector_accumulator #(
|
|
parameter integer NO_ROWS = 12,
|
|
parameter integer NO_COLS = 12,
|
|
parameter integer DATA_WIDTH = 16,
|
|
parameter integer CTRL_WIDTH = 2 // {-1, 0, 1} as 2's complement
|
|
)(
|
|
input clk,
|
|
input rst,
|
|
input valid_in,
|
|
|
|
input [DATA_WIDTH*((NO_ROWS>NO_COLS)?NO_ROWS-1:NO_COLS-1):0] data_row_flat,
|
|
input [$clog2(NO_COLS)-1:0] cols_size_reading,
|
|
|
|
input [CTRL_WIDTH*((NO_ROWS>NO_COLS)?NO_ROWS-1:NO_COLS-1):0] rand_vector_flat,
|
|
|
|
output reg signed [DATA_WIDTH-1 : 0] sum_out,
|
|
output reg valid_out
|
|
);
|
|
|
|
// Internal signals
|
|
integer i;
|
|
reg signed [DATA_WIDTH-1:0] data_element;
|
|
reg signed [CTRL_WIDTH-1:0] ctrl_element;
|
|
reg signed [DATA_WIDTH-1:0] accumulator;
|
|
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
sum_out <= 0;
|
|
valid_out <= 0;
|
|
end else begin
|
|
if (valid_in) begin
|
|
accumulator = 0;
|
|
|
|
for (i = 0; i <= cols_size_reading; i = i + 1) begin///updated logic
|
|
data_element = data_row_flat[i*DATA_WIDTH +: DATA_WIDTH];
|
|
ctrl_element = rand_vector_flat[i*CTRL_WIDTH +: CTRL_WIDTH];
|
|
|
|
if (ctrl_element == 2'sd1)
|
|
accumulator = accumulator + data_element;
|
|
else if (ctrl_element == -2'sd1)
|
|
accumulator = accumulator - data_element;
|
|
// else: ctrl_element == 0 → discard
|
|
end
|
|
|
|
sum_out <= accumulator;
|
|
|
|
valid_out <= 1;
|
|
end else begin
|
|
valid_out <= 0;
|
|
end
|
|
end
|
|
end
|
|
endmodule
|
|
|
|
|