AYAKA_Transformer/rtl/Random_number_generator.v

78 lines
2.2 KiB
Verilog

module random_vector_generator #(
parameter integer S = 2, // Controls sparsity
parameter integer NO_ROWS = 12,
parameter integer NO_COLS = 12, // Number of random values to generate
parameter integer DATA_WIDTH = 2, // 2 bits for {-1, 0, 1}
parameter integer CTRL_WIDTH = 2 // {-1, 0, 1} as 2's complement
)(
input clk,
input rst,
input enable,
input [$clog2(NO_COLS)-1:0] cols_size_reading,
output reg [CTRL_WIDTH*((NO_ROWS>NO_COLS)?NO_ROWS-1:NO_COLS-1):0] rand_vector_flat,
output reg valid
);
// Internal counter to track how many values generated
reg [$clog2(NO_COLS):0] gen_count;
reg generating;
// Array of random numbers (one LFSR reused for simplicity)
wire [15:0] rand_num;
lfsr16 lfsr_inst (
.clk(clk),
.rst(rst),
.out(rand_num)
);
// One generated value
reg signed [DATA_WIDTH-1:0] current_value;
always @(posedge clk) begin
if (rst) begin
gen_count <= 0;
valid <= 0;
generating <= 0;
rand_vector_flat <= 0;
current_value <= 2'sd0;
end else begin
if (enable && !generating) begin
// Start generating new vector
gen_count <= 0;
valid <= 0;
generating <= 1;
end
if (generating && enable) begin
// Decide current value based on rand_num
if (rand_num < (65536 / S)) begin
if (rand_num[0])
current_value <= -2'sd1;
else
current_value <= 2'sd1;
end else begin
current_value <= 2'sd0;
end
// Store current value at gen_count index
rand_vector_flat[gen_count * CTRL_WIDTH +: CTRL_WIDTH] <= current_value;
// Increment counter
gen_count <= gen_count + 1;
// Check if done
if (gen_count == (cols_size_reading - 1)) begin
valid <= 1;
generating <= 0;
end else begin
valid <= 0;
end
end else begin
valid <= 0;
end
end
end
endmodule