From 0dd86e391c103e9bc81954f5ff2972d227fdeeee Mon Sep 17 00:00:00 2001 From: Jan Grabowski Date: Thu, 4 Dec 2025 22:19:09 +0100 Subject: [PATCH 1/4] Initial commit --- HW/memory_weights.sv | 23 +++++ HW/top_module.sv | 149 ++++++++++++++++++++++++++++++ HW/vector_multiplier.sv | 54 +++++++++++ HW/vector_multiplier_generator.sv | 34 +++++++ 4 files changed, 260 insertions(+) create mode 100644 HW/memory_weights.sv create mode 100644 HW/top_module.sv create mode 100644 HW/vector_multiplier.sv create mode 100644 HW/vector_multiplier_generator.sv diff --git a/HW/memory_weights.sv b/HW/memory_weights.sv new file mode 100644 index 0000000..da4f55a --- /dev/null +++ b/HW/memory_weights.sv @@ -0,0 +1,23 @@ +module memory_weights #( + parameter int DATA_WIDTH = 1024, + parameter int ADDR_DEPTH = 1024, + parameter int ADDR_WIDTH = $clog2(ADDR_DEPTH), + parameter RAM_TYPE = "block" +) ( + input logic clk, + input logic ce, + input logic [ADDR_WIDTH-1:0] addr, + output logic [DATA_WIDTH-1:0] dout +); + + (* ram_style = RAM_TYPE *) logic [DATA_WIDTH-1:0] mem[ADDR_DEPTH-1:0] = '{default:0}; + + initial begin + $readmemh("mem_init.mem", mem); + end + + always_ff @(posedge clk) begin + if(ce) dout <= mem[addr]; + end + +endmodule diff --git a/HW/top_module.sv b/HW/top_module.sv new file mode 100644 index 0000000..f1e7a54 --- /dev/null +++ b/HW/top_module.sv @@ -0,0 +1,149 @@ +module top_module #( + parameter int WIDTH = 8, + parameter int WIDTH_B = 32, + parameter int P = 2, //number of parallel features + parameter int Q = 2, //number of modules per feature + parameter int N = 10, + parameter int M = 12, + parameter in M_MUL = 12345, + parameter in Z_WEIGHTS = 5 +) ( + output logic axis_ready, + input logic clk, + input logic rst, + input logic ce, + input logic axis_valid, + input logic [P-1:0][N-1:0][WIDTH-1:0] features, + output logic [P-1:0][M-1:0][WIDTH-1:0] out + // to do -> add more I/O signals + // to do -> AXIS signals module +); + + localparam int DATA_WIDTH = WIDTH*N+WIDTH_B; + + typedef enum logic { + INITIALIZE, + IDLE, + INSERT, + MULTIPLY, + OUT + } t_state; + + t_state state, next_state; + + logic r_ce; + logic [P-1:0][N-1:0][WIDTH-1:0] r_features_in; + logic [WIDTH_B-1:0] bias; + logic [N-1:0][WIDTH-1:0] weights_in; + logic [$clog2(M)-1:0] line_counter = 0; + + logic [P-1:0][WIDTH_B-1:0] acc ; //to do -> parametrize bias width + logic [P-1:0][WIDTH_B-1:0] ai ; + + logic [P-1:0][WIDTH+16-1:0] r_out; //to do -> choose width + + logic [DATA_WIDTH-1:0] mem_data_out; + + memory_weights #( + .DATA_WIDTH ( DATA_WIDTH ), + .ADDR_DEPTH ( M ) + ) u_memory_weights ( + .clk ( clk ), + .ce ( r_ce ), + .addr ( line_counter ), + .dout ( mem_data_out ) + ); + + genvar i; + for(i=0; i parallel memory interface to read multiple weights lines + end + bias = mem_data_out[N<<(3)-1+:WIDTH_B]; + r_features_in <= features; + r_ce <= ce; + end + + OUT: begin + for(int i=0; i>>32) + bias; + end + axis_ready <= 1; + out <= r_out; //to do -> quantize or slice? + end + endcase; + end + end + + + always_comb begin + case (state) + INITIALIZE: begin + //to do -> calculate biases + //to do -> slicing weights and biases module depending on bram size + next_state = IDLE; + end + + IDLE: begin // In this state BRAM address is incremented until it reaches its final line + if (axis_valid) begin + next_state = INSERT; + end else begin + next_state = IDLE; + end + end + + INSERT: begin // In this state, weights lines stored in mem_data_out are sliced in for loop + next_state = MULTIPLY; + end + + MULTIPLY: begin // In this state vector multiplication module calculates output value + next_state = OUT; + end + + OUT: begin // In this state final version of output vector is calculated + next_state <= IDLE; + //to do -> output module + end + endcase + end + +endmodule diff --git a/HW/vector_multiplier.sv b/HW/vector_multiplier.sv new file mode 100644 index 0000000..7a56eda --- /dev/null +++ b/HW/vector_multiplier.sv @@ -0,0 +1,54 @@ +`timescale 1ns / 1ps + +module vector_multiplier #( + parameter int REG_DEPTH = 8, + parameter int NP = 1 +) ( + input logic clk, + input logic rst, + input logic ce, //Przemyśleć + input logic [NP-1:0][REG_DEPTH-1:0] features_in, + input logic [NP-1:0][REG_DEPTH-1:0] weights_in, + output logic [31:0] acc, + output logic [31:0] ai +); + + logic [NP-1:0][REG_DEPTH-1:0] r_features_in; + logic [NP-1:0][REG_DEPTH-1:0] r_weights_in; + + logic [31:0] r_acc; + logic [31:0] r_ai; + + logic [31:0] n_acc; + logic [31:0] n_ai; + + always_ff @ (posedge clk) begin + if(rst) begin + r_features_in <= 0; + r_weights_in <= 0; + end + else begin + r_features_in <= features_in; + r_weights_in <= weights_in; + end + end + + always_comb begin + if(ce) begin + n_acc = 0; + n_ai = 0; + for(int i=0; i Date: Wed, 10 Dec 2025 23:28:24 +0100 Subject: [PATCH 2/4] Nowy top module --- HW/top_module.sv | 141 ++++++++++------------------------------------- 1 file changed, 28 insertions(+), 113 deletions(-) diff --git a/HW/top_module.sv b/HW/top_module.sv index f1e7a54..720f417 100644 --- a/HW/top_module.sv +++ b/HW/top_module.sv @@ -1,149 +1,64 @@ module top_module #( - parameter int WIDTH = 8, - parameter int WIDTH_B = 32, - parameter int P = 2, //number of parallel features - parameter int Q = 2, //number of modules per feature + parameter int PRECISION = 8, + parameter int BIAS_PRECISION = 32, + parameter int NUM_FEATURES = 2, //number of parallel features parameter int N = 10, parameter int M = 12, parameter in M_MUL = 12345, parameter in Z_WEIGHTS = 5 ) ( - output logic axis_ready, + output logic out_valid, + output logic in_ready, + input logic in_valid, + input logic out_ready, input logic clk, input logic rst, input logic ce, - input logic axis_valid, - input logic [P-1:0][N-1:0][WIDTH-1:0] features, - output logic [P-1:0][M-1:0][WIDTH-1:0] out - // to do -> add more I/O signals - // to do -> AXIS signals module + input logic [NUM_FEATURES-1:0][N-1:0][PRECISION-1:0] features, + output logic [NUM_FEATURES-1:0][M-1:0][PRECISION-1:0] out ); - localparam int DATA_WIDTH = WIDTH*N+WIDTH_B; + localparam int BRAM_WIDTH = WIDTH*N+WIDTH_B; typedef enum logic { - INITIALIZE, IDLE, - INSERT, - MULTIPLY, + RUNNING, OUT } t_state; - t_state state, next_state; - - logic r_ce; - logic [P-1:0][N-1:0][WIDTH-1:0] r_features_in; - logic [WIDTH_B-1:0] bias; - logic [N-1:0][WIDTH-1:0] weights_in; - logic [$clog2(M)-1:0] line_counter = 0; - - logic [P-1:0][WIDTH_B-1:0] acc ; //to do -> parametrize bias width - logic [P-1:0][WIDTH_B-1:0] ai ; - - logic [P-1:0][WIDTH+16-1:0] r_out; //to do -> choose width + t_state state; + + logic [NUM_FEATURES-1:0][N-1:0][PRECISION-1:0] latched_features, - logic [DATA_WIDTH-1:0] mem_data_out; - - memory_weights #( - .DATA_WIDTH ( DATA_WIDTH ), - .ADDR_DEPTH ( M ) - ) u_memory_weights ( - .clk ( clk ), - .ce ( r_ce ), - .addr ( line_counter ), - .dout ( mem_data_out ) - ); + logic [NUM_FEATURES-1:0][M-1:0][WIDTH_B-1:0] acc ; + logic [NUM_FEATURES-1:0][WIDTH_B-1:0] ai ; - genvar i; - for(i=0; i parallel memory interface to read multiple weights lines - end - bias = mem_data_out[N<<(3)-1+:WIDTH_B]; - r_features_in <= features; - r_ce <= ce; + RUNNING: begin + in_ready = 0; + // HW team; end OUT: begin - for(int i=0; i>>32) + bias; - end - axis_ready <= 1; - out <= r_out; //to do -> quantize or slice? + out_valid = 1; + if (out_ready) begin + state = IDLE; + end end endcase; end end - - always_comb begin - case (state) - INITIALIZE: begin - //to do -> calculate biases - //to do -> slicing weights and biases module depending on bram size - next_state = IDLE; - end - - IDLE: begin // In this state BRAM address is incremented until it reaches its final line - if (axis_valid) begin - next_state = INSERT; - end else begin - next_state = IDLE; - end - end - - INSERT: begin // In this state, weights lines stored in mem_data_out are sliced in for loop - next_state = MULTIPLY; - end - - MULTIPLY: begin // In this state vector multiplication module calculates output value - next_state = OUT; - end - - OUT: begin // In this state final version of output vector is calculated - next_state <= IDLE; - //to do -> output module - end - endcase - end - endmodule From 2aa20ee5858826457519fda53f31eec5553ba416 Mon Sep 17 00:00:00 2001 From: Dawid Podsiadlo Date: Sat, 13 Dec 2025 21:03:32 +0100 Subject: [PATCH 3/4] =?UTF-8?q?Tablice=20trzeba=20definiowa=C4=87=20w=20te?= =?UTF-8?q?n=20sposob?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HW/top_module.sv | 48 ++++++++++++++++++++++++------------------------ HW/unit_test.sv | 14 ++++++++++++++ 2 files changed, 38 insertions(+), 24 deletions(-) create mode 100644 HW/unit_test.sv diff --git a/HW/top_module.sv b/HW/top_module.sv index 720f417..10bb3e0 100644 --- a/HW/top_module.sv +++ b/HW/top_module.sv @@ -14,51 +14,51 @@ module top_module #( input logic clk, input logic rst, input logic ce, - input logic [NUM_FEATURES-1:0][N-1:0][PRECISION-1:0] features, - output logic [NUM_FEATURES-1:0][M-1:0][PRECISION-1:0] out + input logic [PRECISION-1:0] features [NUM_FEATURES][N], + output logic [PRECISION-1:0] out [NUM_FEATURES][N] ); - localparam int BRAM_WIDTH = WIDTH*N+WIDTH_B; + localparam int BramWidth = WIDTH*N+WIDTH_B; typedef enum logic { IDLE, RUNNING, OUT - } t_state; - - t_state state; + } state_t; - logic [NUM_FEATURES-1:0][N-1:0][PRECISION-1:0] latched_features, - - logic [NUM_FEATURES-1:0][M-1:0][WIDTH_B-1:0] acc ; - logic [NUM_FEATURES-1:0][WIDTH_B-1:0] ai ; - - always_ff @(posedge clk or posedge rst) begin + state_t state; + + logic [PRECISION-1:0] latched_features [NUM_FEATURES][N]; + + logic [WIDTH_B-1:0] acc [NUM_FEATURES][M]; + logic [WIDTH_B-1:0] ai [NUM_FEATURES]; + + always_ff @(posedge clk or posedge rst) begin if (rst) begin state <= IDLE; end else begin - case(state) + unique case(state) IDLE: begin - in_ready = 1; + in_ready <= 1; if (in_valid) begin - latched_features = features; - state = RUNNING; + latched_features <= features; + state <= RUNNING; end end - + RUNNING: begin - in_ready = 0; + in_ready <= 0; // HW team; - end - + end + OUT: begin - out_valid = 1; + out_valid <= 1; if (out_ready) begin - state = IDLE; + state <= IDLE; end - end + end endcase; end end - + endmodule diff --git a/HW/unit_test.sv b/HW/unit_test.sv new file mode 100644 index 0000000..58a6fe1 --- /dev/null +++ b/HW/unit_test.sv @@ -0,0 +1,14 @@ +module unit_test #( + parameter int PRECISION = 8, + parameter int BIAS_PRECISION = 32, + parameter int NUM_FEATURES = 2, //number of parallel features + parameter int N = 10, + parameter int M = 12, + parameter int M_MUL = 12345, + parameter int Z_WEIGHTS = 5 +) ( +); + +logic [PRECISION-1:0] features [N][NUM_FEATURES]; + +endmodule From e8534d39aacfd7d3f824129660432f73903dda01 Mon Sep 17 00:00:00 2001 From: Dawid Podsiadlo Date: Mon, 15 Dec 2025 02:22:46 +0100 Subject: [PATCH 4/4] Unit test --- HW/params.txt | 8 +++ HW/top_module.sv | 7 +-- HW/unit_test.sv | 130 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 132 insertions(+), 13 deletions(-) create mode 100644 HW/params.txt diff --git a/HW/params.txt b/HW/params.txt new file mode 100644 index 0000000..f6ebe26 --- /dev/null +++ b/HW/params.txt @@ -0,0 +1,8 @@ +parameter int PRECISION = 8; +parameter int BIAS_PRECISION = 32; +parameter int NUM_FEATURES = 2; +parameter int N = 10; +parameter int M = 12; +parameter int M_MUL = 12345; +parameter int Z_WEIGHTS = 5; +parameter int NUM_EXAMPLES = 1; diff --git a/HW/top_module.sv b/HW/top_module.sv index 10bb3e0..0d56eba 100644 --- a/HW/top_module.sv +++ b/HW/top_module.sv @@ -40,21 +40,22 @@ module top_module #( unique case(state) IDLE: begin in_ready <= 1; - if (in_valid) begin + if (in_valid && in_ready) begin latched_features <= features; state <= RUNNING; + in_ready <= 0; end end RUNNING: begin - in_ready <= 0; // HW team; end OUT: begin out_valid <= 1; - if (out_ready) begin + if (out_ready && out_valid) begin state <= IDLE; + out_valid <= 0; end end endcase; diff --git a/HW/unit_test.sv b/HW/unit_test.sv index 58a6fe1..897a551 100644 --- a/HW/unit_test.sv +++ b/HW/unit_test.sv @@ -1,14 +1,124 @@ -module unit_test #( - parameter int PRECISION = 8, - parameter int BIAS_PRECISION = 32, - parameter int NUM_FEATURES = 2, //number of parallel features - parameter int N = 10, - parameter int M = 12, - parameter int M_MUL = 12345, - parameter int Z_WEIGHTS = 5 -) ( +module unit_test ( ); -logic [PRECISION-1:0] features [N][NUM_FEATURES]; +`include "params.txt" + + +logic [PRECISION-1:0] raw_examples [N*NUM_FEATURES*NUM_EXAMPLES]; +logic [PRECISION-1:0] examples [NUM_EXAMPLES][NUM_FEATURES][N]; +logic [PRECISION-1:0] features [NUM_FEATURES][N]; +logic [PRECISION-1:0] out [NUM_FEATURES][M]; +logic [PRECISION-1:0] latched_out [NUM_FEATURES][M]; +logic clk = 1; +logic ce = 1; +logic rst = 0; + +integer ex, fea, n, i; + +initial begin + $readmemh("features.bin", raw_examples); + // unflatten + for (i = 0; i < NUM_EXAMPLES*NUM_FEATURES*N; i = i + 1) begin + ex = i / (NUM_FEATURES * N); + fea = (i / N) % NUM_FEATURES; + n = i % N; + examples[ex][fea][n] = raw_examples[i]; + end +end + +always #1 clk = ~clk; + +logic out_ready; +logic out_valid = 0; +logic in_ready; +logic in_valid = 0; + +top_module #( + .PRECISION(PRECISION), + .BIAS_PRECISION(BIAS_PRECISION), + .NUM_FEATURES(NUM_FEATURES), + .N(N), + .M(M), + .M_MUL(M_MUL), + .Z_WEIGHTS(Z_WEIGHTS) +) dut +( + .out_valid(in_valid), + .in_ready(out_ready), + .in_valid(out_valid), + .out_ready(in_ready), + .clk(clk), + .rst(rst), + .ce(ce), + .features(features), + .out(out) +); + +typedef enum logic { + LOAD, + SEND, + RECEIVE, + SAVE, + FINISHED +} state_t; + +state_t stan = LOAD; +logic [31:0] index = 0; + +logic [8*64:1] filename; // 64-char filename buffer +integer file; +integer f, m; + +always_ff @(posedge clk) begin : StateMachine + unique case (stan) + LOAD: begin + if (index < NUM_EXAMPLES) begin + features <= examples[index]; + stan <= SEND; + index += 1; + end else begin + $display("FINISHED"); + stan <= FINISHED; + end + end + SEND: begin + out_valid <= 1; + if (out_valid && out_ready) begin + out_valid <= 0; + stan <= RECEIVE; + end + end + RECEIVE: begin + in_ready <= 1; + if (in_ready && in_valid) begin + in_ready <= 0; + stan <= SAVE; + latched_out <= out; + end + end + SAVE: begin + filename = $sformatf("output_example_%0d.bin", index); + + // Open file for writing + file = $fopen(filename, "wb"); + if (file) begin + // Write latched_out to file + for (int f = 0; f < NUM_FEATURES; f++) begin + for (int m = 0; m < M; m++) begin + $fwrite(file, "%0b\n", latched_out[f][m]); + end + end + $fclose(file); + $display("Saved example %0d to %s", index, filename); + end else begin + $display("ERROR: Could not open file %s", filename); + end + stan <= LOAD; + end + FINISHED: begin + $finish; + end + endcase +end endmodule