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/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 new file mode 100644 index 0000000..0d56eba --- /dev/null +++ b/HW/top_module.sv @@ -0,0 +1,65 @@ +module top_module #( + 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 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 [PRECISION-1:0] features [NUM_FEATURES][N], + output logic [PRECISION-1:0] out [NUM_FEATURES][N] +); + + localparam int BramWidth = WIDTH*N+WIDTH_B; + + typedef enum logic { + IDLE, + RUNNING, + OUT + } state_t; + + 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 + unique case(state) + IDLE: begin + in_ready <= 1; + if (in_valid && in_ready) begin + latched_features <= features; + state <= RUNNING; + in_ready <= 0; + end + end + + RUNNING: begin + // HW team; + end + + OUT: begin + out_valid <= 1; + if (out_ready && out_valid) begin + state <= IDLE; + out_valid <= 0; + end + end + endcase; + end + end + +endmodule diff --git a/HW/unit_test.sv b/HW/unit_test.sv new file mode 100644 index 0000000..897a551 --- /dev/null +++ b/HW/unit_test.sv @@ -0,0 +1,124 @@ +module unit_test ( +); + +`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 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