mirror of
https://github.com/retroSoC/common.git
synced 2026-11-04 22:32:37 +00:00
85 lines
2.6 KiB
Systemverilog
85 lines
2.6 KiB
Systemverilog
// Copyright (c) 2023-2025 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
|
// common is licensed under Mulan PSL v2.
|
|
// You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
// You may obtain a copy of Mulan PSL v2 at:
|
|
// http://license.coscl.org.cn/MulanPSL2
|
|
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
// See the Mulan PSL v2 for more details.
|
|
|
|
`ifndef INC_LFSR_SV
|
|
`define INC_LFSR_SV
|
|
|
|
`include "register.sv"
|
|
|
|
//https://en.wikipedia.org/wiki/Linear-feedback_shift_register
|
|
// MSB -> LSB [DATA_WIDTH-1:0]
|
|
module lfsr_galois #(
|
|
parameter int DATA_WIDTH = 32,
|
|
parameter logic [DATA_WIDTH-1:0] POLY = '0
|
|
) (
|
|
input logic clk_i,
|
|
input logic rst_n_i,
|
|
input logic wr_i,
|
|
input logic [DATA_WIDTH-1:0] dat_i,
|
|
output logic [DATA_WIDTH-1:0] dat_o
|
|
);
|
|
|
|
logic [DATA_WIDTH-1:0] s_shift_d, s_shift_q;
|
|
for (genvar i = 0; i < DATA_WIDTH; i++) begin
|
|
if (i == DATA_WIDTH - 1) begin : LFSR_GALOIS_LAST_BLOCK
|
|
assign s_shift_d[i] = wr_i ? dat_i[i] : s_shift_q[0];
|
|
end else begin : LFSR_GALOIS_NLAST_BLOCK
|
|
if (POLY & (1 << i)) begin : LFSR_GALOIS_HVALUE_BLOCK
|
|
assign s_shift_d[i] = wr_i ? dat_i[i] : s_shift_q[i+1] ^ s_shift_q[0];
|
|
end else begin : LFSR_GALOIS_NHVALUE_BLOCK
|
|
assign s_shift_d[i] = wr_i ? dat_i[i] : s_shift_q[i+1];
|
|
end
|
|
end
|
|
end
|
|
|
|
assign dat_o = s_shift_q;
|
|
dffr #(DATA_WIDTH) u_shift_dffr (
|
|
clk_i,
|
|
rst_n_i,
|
|
s_shift_d,
|
|
s_shift_q
|
|
);
|
|
|
|
endmodule
|
|
|
|
// due to the delay, more recommand to use galois type lfsr
|
|
// NOTE: this module is no ready for use, need more test
|
|
module lfsr_fibonacci #(
|
|
parameter int DATA_WIDTH = 32,
|
|
parameter int SEED = 0
|
|
) (
|
|
input logic clk_i,
|
|
input logic rst_n_i,
|
|
input logic wr_i,
|
|
input logic [DATA_WIDTH-1:0] dat_i,
|
|
output logic [DATA_WIDTH-1:0] dat_o
|
|
);
|
|
|
|
logic [DATA_WIDTH-1:0] s_shift_d, s_shift_q;
|
|
|
|
assign dat_o = s_shift_q;
|
|
for (genvar i = 0; i <= DATA_WIDTH - 1; i++) begin : LFSR_FIBONACCI_BLOCK
|
|
if (i == DATA_WIDTH - 1) begin
|
|
assign s_shift_d[i] = wr_i ? dat_i[i] : s_shift_q[0] ^ s_shift_q[1];
|
|
end else begin
|
|
assign s_shift_d[i] = wr_i ? dat_i[i] : s_shift_q[i+1];
|
|
end
|
|
end
|
|
|
|
dffrc #(DATA_WIDTH, SEED) u_shift_dffrc (
|
|
clk_i,
|
|
rst_n_i,
|
|
s_shift_d,
|
|
s_shift_q
|
|
);
|
|
|
|
endmodule
|
|
`endif
|