diff options
| author | Alejandro Soto <alejandro@34project.org> | 2024-03-06 02:38:24 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2024-03-06 02:38:24 -0600 |
| commit | 3038edc09a2eb15762f2e58533f429489107520b (patch) | |
| tree | f7a45e424d39e6fef0d59e329c1bf6ea206e2886 /rtl/wb2axip/axisrandom.v | |
| parent | 3b62399f92e9faa2602ac30865e5fc3c7c4e12b8 (diff) | |
rtl/wb2axip: add to version control
Diffstat (limited to 'rtl/wb2axip/axisrandom.v')
| -rw-r--r-- | rtl/wb2axip/axisrandom.v | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/rtl/wb2axip/axisrandom.v b/rtl/wb2axip/axisrandom.v new file mode 100644 index 0000000..43d91f9 --- /dev/null +++ b/rtl/wb2axip/axisrandom.v @@ -0,0 +1,136 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Filename: axisrandom +// {{{ +// Project: WB2AXIPSP: bus bridges and other odds and ends +// +// Purpose: An AXI-stream based pseudorandom noise generator +// +// Creator: Dan Gisselquist, Ph.D. +// Gisselquist Technology, LLC +// +//////////////////////////////////////////////////////////////////////////////// +// }}} +// Copyright (C) 2020-2024, Gisselquist Technology, LLC +// {{{ +// +// This file is part of the WB2AXIP project. +// +// The WB2AXIP project contains free software and gateware, licensed under the +// Apache License, Version 2.0 (the "License"). You may not use this project, +// or this file, except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//////////////////////////////////////////////////////////////////////////////// +// }}} +// +`default_nettype none +// +module axisrandom #( + // {{{ + localparam C_AXIS_DATA_WIDTH = 32 + // }}} + ) ( + // {{{ + input wire S_AXI_ACLK, + input wire S_AXI_ARESETN, + // + output reg M_AXIS_TVALID, + input wire M_AXIS_TREADY, + output reg [C_AXIS_DATA_WIDTH-1:0] M_AXIS_TDATA + // }}} + ); + + localparam INITIAL_FILL = { 1'b1, {(C_AXIS_DATA_WIDTH-1){1'b0}} }; + localparam LGPOLY = 31; + localparam [LGPOLY-1:0] CORE_POLY = { 31'h00_00_20_01 }; + localparam [C_AXIS_DATA_WIDTH-1:0] POLY + = { CORE_POLY, {(C_AXIS_DATA_WIDTH-31){1'b0}} }; + + // M_AXIS_TVALID + // {{{ + initial M_AXIS_TVALID = 1'b0; + always @(posedge S_AXI_ACLK) + if (!S_AXI_ARESETN) + M_AXIS_TVALID <= 1'b0; + else + M_AXIS_TVALID <= 1'b1; + // }}} + + // M_AXIS_TDATA + // {{{ + // + // Note--this setup is *FAR* from cryptographically random. + // + initial M_AXIS_TDATA = INITIAL_FILL; + always @(posedge S_AXI_ACLK) + if (!S_AXI_ARESETN) + M_AXIS_TDATA <= INITIAL_FILL; + else if (M_AXIS_TREADY) + begin + M_AXIS_TDATA <= M_AXIS_TDATA >> 1; + M_AXIS_TDATA[C_AXIS_DATA_WIDTH-1] <= ^(M_AXIS_TDATA & POLY); + end + // }}} + + // Verilator lint_off UNUSED + // {{{ + wire unused; + assign unused = &{ 1'b0 }; + // Verilator lint_on UNUSED + // }}} +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// Formal properties used in verfiying this core +// {{{ +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +`ifdef FORMAL + reg f_past_valid; + + initial f_past_valid = 1'b0; + always @(posedge S_AXI_ACLK) + f_past_valid <= 1'b1; + + always @(*) + if (!f_past_valid) + assume(!S_AXI_ARESETN); + + // Make certain this polynomial will never degenerate, and so that + // this random number stream will go on for ever--eventually repeating + // after 2^LGPOLY-1 (hopefully) elements. + always @(*) + assert(M_AXIS_TDATA[C_AXIS_DATA_WIDTH-1 + :C_AXIS_DATA_WIDTH-LGPOLY] != 0); + + // AXI stream has only one significant property + // {{{ + // Here we'll modify it slightly for our purposes + always @(posedge S_AXI_ACLK) + if (!f_past_valid || $past(!S_AXI_ARESETN)) + assert(!M_AXIS_TVALID); + else begin + assert(M_AXIS_TVALID); + if ($past(M_AXIS_TVALID && !M_AXIS_TREADY)) + // Normally I'd assesrt M_AXIS_TVALID here, not above, + // but this core *ALWAYS* produces data + assert($stable(M_AXIS_TDATA)); + else if ($past(M_AXIS_TVALID)) + // Insist that the data always changes otherwise + assert($changed(M_AXIS_TDATA)); + end + // }}} +`endif +// }}} +endmodule |
