78 lines
2.2 KiB
Verilog
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
|
|
|
|
|