forked from ZipCPU/wb2axip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
axisrandom.v
136 lines (128 loc) · 3.94 KB
/
axisrandom.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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-2021, 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