1
0
mirror of https://github.com/corundum/corundum.git synced 2025-01-30 08:32:52 +08:00

Update LFSR module

This commit is contained in:
Alex Forencich 2017-06-09 21:17:28 -07:00
parent 69253d2d83
commit 9a507b388d
13 changed files with 328 additions and 191 deletions

View File

@ -64,15 +64,16 @@ lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(input_axis_tdata),
.lfsr_in(crc_state),
.lfsr_out(crc_next)
.state_in(crc_state),
.data_out(),
.state_out(crc_next)
);
always @(posedge clk) begin

View File

@ -72,120 +72,128 @@ lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(input_axis_tdata[7:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next0)
.state_in(crc_state),
.data_out(),
.state_out(crc_next0)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(16),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_16 (
.data_in(input_axis_tdata[15:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next1)
.state_in(crc_state),
.data_out(),
.state_out(crc_next1)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(24),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_24 (
.data_in(input_axis_tdata[23:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next2)
.state_in(crc_state),
.data_out(),
.state_out(crc_next2)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(32),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_32 (
.data_in(input_axis_tdata[31:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next3)
.state_in(crc_state),
.data_out(),
.state_out(crc_next3)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(40),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_40 (
.data_in(input_axis_tdata[39:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next4)
.state_in(crc_state),
.data_out(),
.state_out(crc_next4)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(48),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_48 (
.data_in(input_axis_tdata[47:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next5)
.state_in(crc_state),
.data_out(),
.state_out(crc_next5)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(56),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_56 (
.data_in(input_axis_tdata[55:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next6)
.state_in(crc_state),
.data_out(),
.state_out(crc_next6)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(64),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_64 (
.data_in(input_axis_tdata[63:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next7)
.state_in(crc_state),
.data_out(),
.state_out(crc_next7)
);
always @(posedge clk) begin

View File

@ -106,15 +106,16 @@ lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(input_axis_tdata_d3),
.lfsr_in(crc_state),
.lfsr_out(crc_next)
.state_in(crc_state),
.data_out(),
.state_out(crc_next)
);
always @* begin

View File

@ -121,75 +121,80 @@ lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(last_cycle ? input_axis_tdata_d0[39:32] : input_axis_tdata[7:0]),
.lfsr_in(last_cycle ? crc_state3 : crc_state),
.lfsr_out(crc_next0)
.state_in(last_cycle ? crc_state3 : crc_state),
.data_out(),
.state_out(crc_next0)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(16),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_16 (
.data_in(last_cycle ? input_axis_tdata_d0[47:32] : input_axis_tdata[15:0]),
.lfsr_in(last_cycle ? crc_state3 : crc_state),
.lfsr_out(crc_next1)
.state_in(last_cycle ? crc_state3 : crc_state),
.data_out(),
.state_out(crc_next1)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(24),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_24 (
.data_in(last_cycle ? input_axis_tdata_d0[55:32] : input_axis_tdata[23:0]),
.lfsr_in(last_cycle ? crc_state3 : crc_state),
.lfsr_out(crc_next2)
.state_in(last_cycle ? crc_state3 : crc_state),
.data_out(),
.state_out(crc_next2)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(32),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_32 (
.data_in(last_cycle ? input_axis_tdata_d0[63:32] : input_axis_tdata[31:0]),
.lfsr_in(last_cycle ? crc_state3 : crc_state),
.lfsr_out(crc_next3)
.state_in(last_cycle ? crc_state3 : crc_state),
.data_out(),
.state_out(crc_next3)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(64),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_64 (
.data_in(input_axis_tdata[63:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next7)
.state_in(crc_state),
.data_out(),
.state_out(crc_next7)
);
always @* begin

View File

@ -99,15 +99,16 @@ lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(output_axis_tdata_int),
.lfsr_in(crc_state),
.lfsr_out(crc_next)
.state_in(crc_state),
.data_out(),
.state_out(crc_next)
);
always @* begin

View File

@ -123,120 +123,128 @@ lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(fcs_input_tdata[7:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next0)
.state_in(crc_state),
.data_out(),
.state_out(crc_next0)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(16),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_16 (
.data_in(fcs_input_tdata[15:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next1)
.state_in(crc_state),
.data_out(),
.state_out(crc_next1)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(24),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_24 (
.data_in(fcs_input_tdata[23:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next2)
.state_in(crc_state),
.data_out(),
.state_out(crc_next2)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(32),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_32 (
.data_in(fcs_input_tdata[31:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next3)
.state_in(crc_state),
.data_out(),
.state_out(crc_next3)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(40),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_40 (
.data_in(fcs_input_tdata[39:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next4)
.state_in(crc_state),
.data_out(),
.state_out(crc_next4)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(48),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_48 (
.data_in(fcs_input_tdata[47:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next5)
.state_in(crc_state),
.data_out(),
.state_out(crc_next5)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(56),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_56 (
.data_in(fcs_input_tdata[55:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next6)
.state_in(crc_state),
.data_out(),
.state_out(crc_next6)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(64),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_64 (
.data_in(fcs_input_tdata[63:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next7)
.state_in(crc_state),
.data_out(),
.state_out(crc_next7)
);
function [3:0] keep2count;

View File

@ -117,15 +117,16 @@ lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(gmii_rxd_d4),
.lfsr_in(crc_state),
.lfsr_out(crc_next)
.state_in(crc_state),
.data_out(),
.state_out(crc_next)
);
always @* begin

View File

@ -108,15 +108,16 @@ lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(input_tdata_reg),
.lfsr_in(crc_state),
.lfsr_out(crc_next)
.state_in(crc_state),
.data_out(),
.state_out(crc_next)
);
always @* begin

View File

@ -120,75 +120,80 @@ lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(last_cycle ? xgmii_rxd_d1[39:32] : xgmii_rxd_d0[7:0]),
.lfsr_in(last_cycle ? crc_state3 : crc_state),
.lfsr_out(crc_next0)
.state_in(last_cycle ? crc_state3 : crc_state),
.data_out(),
.state_out(crc_next0)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(16),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_16 (
.data_in(last_cycle ? xgmii_rxd_d1[47:32] : xgmii_rxd_d0[15:0]),
.lfsr_in(last_cycle ? crc_state3 : crc_state),
.lfsr_out(crc_next1)
.state_in(last_cycle ? crc_state3 : crc_state),
.data_out(),
.state_out(crc_next1)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(24),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_24 (
.data_in(last_cycle ? xgmii_rxd_d1[55:32] : xgmii_rxd_d0[23:0]),
.lfsr_in(last_cycle ? crc_state3 : crc_state),
.lfsr_out(crc_next2)
.state_in(last_cycle ? crc_state3 : crc_state),
.data_out(),
.state_out(crc_next2)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(32),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_32 (
.data_in(last_cycle ? xgmii_rxd_d1[63:32] : xgmii_rxd_d0[31:0]),
.lfsr_in(last_cycle ? crc_state3 : crc_state),
.lfsr_out(crc_next3)
.state_in(last_cycle ? crc_state3 : crc_state),
.data_out(),
.state_out(crc_next3)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(64),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_64 (
.data_in(xgmii_rxd_d0[63:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next7)
.state_in(crc_state),
.data_out(),
.state_out(crc_next7)
);
// detect control characters

View File

@ -129,120 +129,128 @@ lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(input_tdata_reg[7:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next0)
.state_in(crc_state),
.data_out(),
.state_out(crc_next0)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(16),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_16 (
.data_in(input_tdata_reg[15:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next1)
.state_in(crc_state),
.data_out(),
.state_out(crc_next1)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(24),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_24 (
.data_in(input_tdata_reg[23:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next2)
.state_in(crc_state),
.data_out(),
.state_out(crc_next2)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(32),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_32 (
.data_in(input_tdata_reg[31:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next3)
.state_in(crc_state),
.data_out(),
.state_out(crc_next3)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(40),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_40 (
.data_in(input_tdata_reg[39:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next4)
.state_in(crc_state),
.data_out(),
.state_out(crc_next4)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(48),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_48 (
.data_in(input_tdata_reg[47:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next5)
.state_in(crc_state),
.data_out(),
.state_out(crc_next5)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(56),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_56 (
.data_in(input_tdata_reg[55:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next6)
.state_in(crc_state),
.data_out(),
.state_out(crc_next6)
);
lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(64),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_64 (
.data_in(input_tdata_reg[63:0]),
.lfsr_in(crc_state),
.lfsr_out(crc_next7)
.state_in(crc_state),
.data_out(),
.state_out(crc_next7)
);
function [3:0] keep2count;

View File

@ -108,15 +108,16 @@ lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(gmii_rxd_d4),
.lfsr_in(crc_state),
.lfsr_out(crc_next)
.state_in(crc_state),
.data_out(),
.state_out(crc_next)
);
always @* begin

View File

@ -96,15 +96,16 @@ lfsr #(
.LFSR_WIDTH(32),
.LFSR_POLY(32'h4c11db7),
.LFSR_CONFIG("GALOIS"),
.LFSR_FEED_FORWARD(0),
.REVERSE(1),
.DATA_WIDTH(8),
.OUTPUT_WIDTH(32),
.STYLE("AUTO")
)
eth_crc_8 (
.data_in(gmii_txd_next),
.lfsr_in(crc_state),
.lfsr_out(crc_next)
.state_in(crc_state),
.data_out(),
.state_out(crc_next)
);
always @* begin

View File

@ -37,19 +37,20 @@ module lfsr #
parameter LFSR_POLY = 31'h10000001,
// LFSR configuration: "GALOIS", "FIBONACCI"
parameter LFSR_CONFIG = "FIBONACCI",
// LFSR feed forward enable
parameter LFSR_FEED_FORWARD = 0,
// bit-reverse input and output
parameter REVERSE = 0,
// width of data input
parameter DATA_WIDTH = 8,
// width of CRC/LFSR output
parameter OUTPUT_WIDTH = LFSR_WIDTH,
// implementation style: "AUTO", "LOOP", "REDUCTION"
parameter STYLE = "AUTO"
)
(
input wire [DATA_WIDTH-1:0] data_in,
input wire [LFSR_WIDTH-1:0] lfsr_in,
output wire [OUTPUT_WIDTH-1:0] lfsr_out
input wire [LFSR_WIDTH-1:0] state_in,
output wire [DATA_WIDTH-1:0] data_out,
output wire [LFSR_WIDTH-1:0] state_out
);
/*
@ -65,15 +66,19 @@ Ports:
data_in
Data bits to be XORed with the LFSR feedback path (DATA_WIDTH bits)
Data bits to be shifted through the LFSR (DATA_WIDTH bits)
lfsr_in
state_in
LFSR/CRC current state input (LFSR_WIDTH bits)
lfsr_out
data_out
LFSR/CRC next state output (OUTPUT_WIDTH bits)
Data bits shifted out of LFSR (DATA_WIDTH bits)
state_out
LFSR/CRC next state output (LFSR_WIDTH bits)
Parameters:
@ -103,37 +108,60 @@ generators and checkers.
Fibonacci style (example for 64b66b scrambler, 0x8000000001)
,-----------------------------(+)<------------------------------,
DIN (LSB first)
|
V
(+)<---------------------------(+)<-----------------------------.
| ^ |
| .----. .----. .----. | .----. .----. .----. |
`->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |->(+)<-DIN (MSB first)
'----' '----' '----' '----' '----' '----'
+->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |--'
| '----' '----' '----' '----' '----' '----'
V
DOUT
Galois style (example for CRC16, 0x8005)
,-------------------+---------------------------------+------------,
,-------------------+-------------------------+----------(+)<-- DIN (MSB first)
| | | ^
| .----. .----. V .----. .----. V .----. |
`->| 0 |->| 1 |->(+)->| 2 |->...->| 14 |->(+)->| 15 |--+---> DOUT
'----' '----' '----' '----' '----'
LFSR_FEED_FORWARD
Generate feed forward instead of feed back LFSR. Enable this for PRBS checking and self-
synchronous descrambling.
Fibonacci feed-forward style (example for 64b66b descrambler, 0x8000000001)
DIN (LSB first)
|
| .----. .----. .----. .----. .----. .----.
+->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |--.
| '----' '----' '----' | '----' '----' '----' |
| V |
(+)<---------------------------(+)------------------------------'
|
V
DOUT
Galois feed-forward style
,-------------------+-------------------------+------------+--- DIN (MSB first)
| | | |
| .----. .----. V .----. .----. .----. V .----. |
`->| 0 |->| 1 |->(+)->| 2 |->| 3 |->...->| 14 |->(+)->| 15 |->(+)<-DIN (MSB first)
'----' '----' '----' '----' '----' '----'
| .----. .----. V .----. .----. V .----. V
`->| 0 |->| 1 |->(+)->| 2 |->...->| 14 |->(+)->| 15 |->(+)-> DOUT
'----' '----' '----' '----' '----'
REVERSE
Bit-reverse LFSR input and output.
Bit-reverse LFSR input and output. Shifts MSB first by default, set REVERSE for LSB first.
DATA_WIDTH
Specify width of input data bus. The module will perform one shift per input data bit,
so if the input data bus is not required tie data_in to zero and set DATA_WIDTH to the
required number of shifts per clock cycle.
OUTPUT_WIDTH
Specify width of output data bus. Defaults to LFSR_WIDTH. Mainly useful for extending
the output width for LFSRs. Ensure that lfsr_out is properly shifted and truncated so
that feeding it back around to lfsr_in produces the expected result. Note that if
OUTPUT_WIDTH is smaller than LFSR_WIDTH, it may not be possible to get the LFSR to
feed back correctly.
Specify width of input and output data bus. The module will perform one shift per input
data bit, so if the input data bus is not required tie data_in to zero and set DATA_WIDTH
to the required number of shifts per clock cycle.
STYLE
@ -151,27 +179,29 @@ synthesis translate directives.
Settings for common LFSR/CRC implementations:
Name Configuration Length Polynomial Initial value Notes
CRC16-IBM Galois, bit-reverse 16 16'h8005 16'hffff
CRC16-CCITT Galois 16 16'h1021 16'h1d0f
CRC32 Galois, bit-reverse 32 32'h04c11db7 32'hffffffff Ethernet FCS; invert final output
PRBS6 Fibonacci 6 6'h21 any
PRBS7 Fibonacci 7 7'h41 amy
PRBS7 Fibonacci 7 7'h41 any
PRBS9 Fibonacci 9 9'h021 any ITU V.52
PRBS10 Fibonacci 10 10'h081 any ITU
PRBS11 Fibonacci 11 11'h201 any ITU O.152
PRBS15 Fibonacci 15 15'h4001 any ITU O.152
PRBS15 Fibonacci, inverted 15 15'h4001 any ITU O.152
PRBS17 Fibonacci 17 17'h04001 any
PRBS20 Fibonacci 20 20'h00009 any ITU V.57
PRBS23 Fibonacci 23 23'h040001 any ITU O.151
PRBS31 Fibonacci 31 31'h10000001 any
64b66b Fibonacci 58 58'h8000000001 any 10G Ethernet
128b130b Fibonacci 23 23'h210125 any PCIe gen 3
PRBS23 Fibonacci, inverted 23 23'h040001 any ITU O.151
PRBS29 Fibonacci, inverted 29 29'h08000001 any
PRBS31 Fibonacci, inverted 31 31'h10000001 any
64b66b Fibonacci, bit-reverse 58 58'h8000000001 any 10G Ethernet
128b130b Galois, bit-reverse 23 23'h210125 any PCIe gen 3
*/
// STATE_WIDTH is OUTPUT_WIDTH or LFSR_WIDTH, whichever is larger
parameter STATE_WIDTH = OUTPUT_WIDTH > LFSR_WIDTH ? OUTPUT_WIDTH : LFSR_WIDTH;
reg [LFSR_WIDTH-1:0] lfsr_mask_state[STATE_WIDTH-1:0];
reg [DATA_WIDTH-1:0] lfsr_mask_data[STATE_WIDTH-1:0];
reg [LFSR_WIDTH-1:0] lfsr_mask_state[LFSR_WIDTH-1:0];
reg [DATA_WIDTH-1:0] lfsr_mask_data[LFSR_WIDTH-1:0];
reg [LFSR_WIDTH-1:0] output_mask_state[DATA_WIDTH-1:0];
reg [DATA_WIDTH-1:0] output_mask_data[DATA_WIDTH-1:0];
reg [LFSR_WIDTH-1:0] state_val = 0;
reg [DATA_WIDTH-1:0] data_val = 0;
@ -180,13 +210,18 @@ integer i, j, k;
initial begin
// init bit masks
for (i = 0; i < STATE_WIDTH; i = i + 1) begin
for (i = 0; i < LFSR_WIDTH; i = i + 1) begin
lfsr_mask_state[i] = {LFSR_WIDTH{1'b0}};
if (i < LFSR_WIDTH) begin
lfsr_mask_state[i][i] = 1'b1;
end
lfsr_mask_data[i] = {DATA_WIDTH{1'b0}};
end
for (i = 0; i < DATA_WIDTH; i = i + 1) begin
output_mask_state[i] = {LFSR_WIDTH{1'b0}};
if (i < LFSR_WIDTH) begin
output_mask_state[i][i] = 1'b1;
end
output_mask_data[i] = {DATA_WIDTH{1'b0}};
end
// simulate shift register
if (LFSR_CONFIG == "FIBONACCI") begin
@ -199,7 +234,7 @@ initial begin
data_val = data_val ^ (1 << i);
// add XOR inputs from correct indicies
for (j = 1; j < STATE_WIDTH; j = j + 1) begin
for (j = 1; j < LFSR_WIDTH; j = j + 1) begin
if (LFSR_POLY & (1 << j)) begin
state_val = lfsr_mask_state[j-1] ^ state_val;
data_val = lfsr_mask_data[j-1] ^ data_val;
@ -207,10 +242,21 @@ initial begin
end
// shift
for (j = STATE_WIDTH-1; j > 0; j = j - 1) begin
for (j = LFSR_WIDTH-1; j > 0; j = j - 1) begin
lfsr_mask_state[j] = lfsr_mask_state[j-1];
lfsr_mask_data[j] = lfsr_mask_data[j-1];
end
for (j = DATA_WIDTH-1; j > 0; j = j - 1) begin
output_mask_state[j] = output_mask_state[j-1];
output_mask_data[j] = output_mask_data[j-1];
end
output_mask_state[0] = state_val;
output_mask_data[0] = data_val;
if (LFSR_FEED_FORWARD) begin
// only shift in new input data
state_val = {LFSR_WIDTH{1'b0}};
data_val = 1 << i;
end
lfsr_mask_state[0] = state_val;
lfsr_mask_data[0] = data_val;
end
@ -224,15 +270,26 @@ initial begin
data_val = data_val ^ (1 << i);
// shift
for (j = STATE_WIDTH-1; j > 0; j = j - 1) begin
for (j = LFSR_WIDTH-1; j > 0; j = j - 1) begin
lfsr_mask_state[j] = lfsr_mask_state[j-1];
lfsr_mask_data[j] = lfsr_mask_data[j-1];
end
for (j = DATA_WIDTH-1; j > 0; j = j - 1) begin
output_mask_state[j] = output_mask_state[j-1];
output_mask_data[j] = output_mask_data[j-1];
end
output_mask_state[0] = state_val;
output_mask_data[0] = data_val;
if (LFSR_FEED_FORWARD) begin
// only shift in new input data
state_val = {LFSR_WIDTH{1'b0}};
data_val = 1 << i;
end
lfsr_mask_state[0] = state_val;
lfsr_mask_data[0] = data_val;
// add XOR inputs at correct indicies
for (j = 1; j < STATE_WIDTH; j = j + 1) begin
for (j = 1; j < LFSR_WIDTH; j = j + 1) begin
if (LFSR_POLY & (1 << j)) begin
lfsr_mask_state[j] = lfsr_mask_state[j] ^ state_val;
lfsr_mask_data[j] = lfsr_mask_data[j] ^ data_val;
@ -247,19 +304,27 @@ initial begin
// reverse bits if selected
if (REVERSE) begin
// reverse order
for (i = 0; i < OUTPUT_WIDTH/2; i = i + 1) begin
for (i = 0; i < LFSR_WIDTH/2; i = i + 1) begin
state_val = lfsr_mask_state[i];
data_val = lfsr_mask_data[i];
lfsr_mask_state[i] = lfsr_mask_state[OUTPUT_WIDTH-i-1];
lfsr_mask_data[i] = lfsr_mask_data[OUTPUT_WIDTH-i-1];
lfsr_mask_state[OUTPUT_WIDTH-i-1] = state_val;
lfsr_mask_data[OUTPUT_WIDTH-i-1] = data_val;
lfsr_mask_state[i] = lfsr_mask_state[LFSR_WIDTH-i-1];
lfsr_mask_data[i] = lfsr_mask_data[LFSR_WIDTH-i-1];
lfsr_mask_state[LFSR_WIDTH-i-1] = state_val;
lfsr_mask_data[LFSR_WIDTH-i-1] = data_val;
end
for (i = 0; i < DATA_WIDTH/2; i = i + 1) begin
state_val = output_mask_state[i];
data_val = output_mask_data[i];
output_mask_state[i] = output_mask_state[DATA_WIDTH-i-1];
output_mask_data[i] = output_mask_data[DATA_WIDTH-i-1];
output_mask_state[DATA_WIDTH-i-1] = state_val;
output_mask_data[DATA_WIDTH-i-1] = data_val;
end
// reverse bits
for (i = 0; i < OUTPUT_WIDTH; i = i + 1) begin
for (i = 0; i < LFSR_WIDTH; i = i + 1) begin
state_val = 0;
for (j = 0; j < STATE_WIDTH; j = j + 1) begin
state_val[j] = lfsr_mask_state[i][STATE_WIDTH-j-1];
for (j = 0; j < LFSR_WIDTH; j = j + 1) begin
state_val[j] = lfsr_mask_state[i][LFSR_WIDTH-j-1];
end
lfsr_mask_state[i] = state_val;
@ -269,9 +334,22 @@ initial begin
end
lfsr_mask_data[i] = data_val;
end
for (i = 0; i < DATA_WIDTH; i = i + 1) begin
state_val = 0;
for (j = 0; j < LFSR_WIDTH; j = j + 1) begin
state_val[j] = output_mask_state[i][LFSR_WIDTH-j-1];
end
output_mask_state[i] = state_val;
data_val = 0;
for (j = 0; j < DATA_WIDTH; j = j + 1) begin
data_val[j] = output_mask_data[i][DATA_WIDTH-j-1];
end
output_mask_data[i] = data_val;
end
end
// for (i = 0; i < OUTPUT_WIDTH; i = i + 1) begin
// for (i = 0; i < LFSR_WIDTH; i = i + 1) begin
// $display("%b %b", lfsr_mask_state[i], lfsr_mask_data[i]);
// end
end
@ -300,8 +378,11 @@ if (STYLE_INT == "REDUCTION") begin
// slightly smaller than generated code with Quartus
// --> better for simulation
for (n = 0; n < OUTPUT_WIDTH; n = n + 1) begin : loop
assign lfsr_out[n] = ^{(lfsr_in & lfsr_mask_state[n]), (data_in & lfsr_mask_data[n])};
for (n = 0; n < LFSR_WIDTH; n = n + 1) begin : loop1
assign state_out[n] = ^{(state_in & lfsr_mask_state[n]), (data_in & lfsr_mask_data[n])};
end
for (n = 0; n < DATA_WIDTH; n = n + 1) begin : loop2
assign data_out[n] = ^{(state_in & output_mask_state[n]), (data_in & output_mask_data[n])};
end
end else if (STYLE_INT == "LOOP") begin
@ -312,21 +393,36 @@ end else if (STYLE_INT == "LOOP") begin
// same size as generated code with Quartus
// --> better for synthesis
reg [OUTPUT_WIDTH-1:0] lfsr_out_reg = 0;
reg [LFSR_WIDTH-1:0] state_out_reg = 0;
reg [DATA_WIDTH-1:0] data_out_reg = 0;
assign lfsr_out = lfsr_out_reg;
assign state_out = state_out_reg;
assign data_out = data_out_reg;
always @* begin
for (i = 0; i < OUTPUT_WIDTH; i = i + 1) begin
lfsr_out_reg[i] = 0;
for (j = 0; j < STATE_WIDTH; j = j + 1) begin
for (i = 0; i < LFSR_WIDTH; i = i + 1) begin
state_out_reg[i] = 0;
for (j = 0; j < LFSR_WIDTH; j = j + 1) begin
if (lfsr_mask_state[i][j]) begin
lfsr_out_reg[i] = lfsr_out_reg[i] ^ lfsr_in[j];
state_out_reg[i] = state_out_reg[i] ^ state_in[j];
end
end
for (j = 0; j < DATA_WIDTH; j = j + 1) begin
if (lfsr_mask_data[i][j]) begin
lfsr_out_reg[i] = lfsr_out_reg[i] ^ data_in[j];
state_out_reg[i] = state_out_reg[i] ^ data_in[j];
end
end
end
for (i = 0; i < DATA_WIDTH; i = i + 1) begin
data_out_reg[i] = 0;
for (j = 0; j < LFSR_WIDTH; j = j + 1) begin
if (output_mask_state[i][j]) begin
data_out_reg[i] = data_out_reg[i] ^ state_in[j];
end
end
for (j = 0; j < DATA_WIDTH; j = j + 1) begin
if (output_mask_data[i][j]) begin
data_out_reg[i] = data_out_reg[i] ^ data_in[j];
end
end
end