1 |
2 |
robfinch |
// ============================================================================
|
2 |
|
|
// 2011 Robert Finch
|
3 |
|
|
// robfinch@<remove>opencores.ca
|
4 |
|
|
//
|
5 |
|
|
// rtfRandom.v
|
6 |
|
|
// Random number generator.
|
7 |
|
|
//
|
8 |
|
|
//
|
9 |
|
|
// This source file is free software: you can redistribute it and/or modify
|
10 |
|
|
// it under the terms of the GNU Lesser General Public License as published
|
11 |
|
|
// by the Free Software Foundation, either version 3 of the License, or
|
12 |
|
|
// (at your option) any later version.
|
13 |
|
|
//
|
14 |
|
|
// This source file is distributed in the hope that it will be useful,
|
15 |
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16 |
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17 |
|
|
// GNU General Public License for more details.
|
18 |
|
|
//
|
19 |
|
|
// You should have received a copy of the GNU General Public License
|
20 |
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
21 |
|
|
//
|
22 |
|
|
// Reg no.
|
23 |
|
|
// 0 random output bits [31:16]
|
24 |
|
|
// 1 random output bits [15: 0]
|
25 |
|
|
// 2 not used
|
26 |
|
|
// 3 not used
|
27 |
|
|
// 4 m_z seed setting bits [31:16]
|
28 |
|
|
// 5 m_z seed setting bits [15 :0]
|
29 |
|
|
// 6 m_w seed setting bits [31:16]
|
30 |
|
|
// 7 m_w seed setting bits [15 :0]
|
31 |
|
|
//
|
32 |
|
|
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
33 |
|
|
// |WISHBONE Datasheet
|
34 |
|
|
// |WISHBONE SoC Architecture Specification, Revision B.3
|
35 |
|
|
// |
|
36 |
|
|
// |Description: Specifications:
|
37 |
|
|
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
38 |
|
|
// |General Description: random number generator
|
39 |
|
|
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
40 |
|
|
// |Supported Cycles: SLAVE,READ/WRITE
|
41 |
|
|
// | SLAVE,BLOCK READ/WRITE
|
42 |
|
|
// | SLAVE,RMW
|
43 |
|
|
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
44 |
|
|
// |Data port, size: 16 bit
|
45 |
|
|
// |Data port, granularity: 16 bit
|
46 |
|
|
// |Data port, maximum operand size: 16 bit
|
47 |
|
|
// |Data transfer ordering: Undefined
|
48 |
|
|
// |Data transfer sequencing: Undefined
|
49 |
|
|
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
50 |
|
|
// |Clock frequency constraints: none
|
51 |
|
|
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
52 |
|
|
// |Supported signal list and Signal Name WISHBONE equiv.
|
53 |
|
|
// |cross reference to equivalent ack_o ACK_O
|
54 |
|
|
// |WISHBONE signals adr_i[43:0] ADR_I()
|
55 |
|
|
// | clk_i CLK_I
|
56 |
|
|
// | rst_i RST_I()
|
57 |
|
|
// | dat_i(15:0) DAT_I()
|
58 |
|
|
// | dat_o(15:0) DAT_O()
|
59 |
|
|
// | cyc_i CYC_I
|
60 |
|
|
// | stb_i STB_I
|
61 |
|
|
// | we_i WE_I
|
62 |
|
|
// |
|
63 |
|
|
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
64 |
|
|
// |Special requirements:
|
65 |
|
|
// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
66 |
|
|
//
|
67 |
|
|
// ============================================================================
|
68 |
|
|
//
|
69 |
|
|
// Uses George Marsaglia's multiply method
|
70 |
|
|
//
|
71 |
|
|
// m_w = <choose-initializer>; /* must not be zero */
|
72 |
|
|
// m_z = <choose-initializer>; /* must not be zero */
|
73 |
|
|
//
|
74 |
|
|
// uint get_random()
|
75 |
|
|
// {
|
76 |
|
|
// m_z = 36969 * (m_z & 65535) + (m_z >> 16);
|
77 |
|
|
// m_w = 18000 * (m_w & 65535) + (m_w >> 16);
|
78 |
|
|
// return (m_z << 16) + m_w; /* 32-bit result */
|
79 |
|
|
// }
|
80 |
|
|
//
|
81 |
|
|
module rtfRandom(rst_i, clk_i, cyc_i, stb_i, ack_o, we_i, adr_i, dat_i, dat_o, vol_o);
|
82 |
|
|
input rst_i;
|
83 |
|
|
input clk_i;
|
84 |
|
|
input cyc_i;
|
85 |
|
|
input stb_i;
|
86 |
|
|
output ack_o;
|
87 |
|
|
input we_i;
|
88 |
|
|
input [43:0] adr_i;
|
89 |
|
|
input [15:0] dat_i;
|
90 |
|
|
output [15:0] dat_o;
|
91 |
|
|
reg [15:0] dat_o;
|
92 |
|
|
output vol_o; // outputting a vclatile register
|
93 |
|
|
|
94 |
|
|
wire cs = cyc_i && stb_i && (adr_i[43:4]==40'hFFF_FFDC_0C0);
|
95 |
|
|
assign ack_o = cs;
|
96 |
|
|
assign vol_o = cs && !we_i && (adr_i[3:1]==3'd0 || adr_i[3:1]==3'd1);
|
97 |
|
|
|
98 |
|
|
reg [31:0] m_z;
|
99 |
|
|
reg [31:0] m_w;
|
100 |
|
|
reg [31:0] next_m_z;
|
101 |
|
|
reg [31:0] next_m_w;
|
102 |
|
|
reg [31:0] out;
|
103 |
|
|
|
104 |
|
|
always @(m_z or m_w)
|
105 |
|
|
begin
|
106 |
|
|
next_m_z <= (18'h36969 * m_z[15:0]) + m_z[31:16];
|
107 |
|
|
next_m_w <= (18'h18000 * m_w[15:0]) + m_w[31:16];
|
108 |
|
|
end
|
109 |
|
|
|
110 |
|
|
// Register read path
|
111 |
|
|
//
|
112 |
|
|
always @(cs or adr_i or out or m_z or m_w)
|
113 |
|
|
if (cs)
|
114 |
|
|
case(adr_i[3:1])
|
115 |
|
|
3'd0: dat_o <= out[31:16];
|
116 |
|
|
3'd1: dat_o <= out[15: 0];
|
117 |
|
|
// Uncomment these for register read-back
|
118 |
|
|
// 3'd4: dat_o <= m_z[31:16];
|
119 |
|
|
// 3'd5: dat_o <= m_z[15: 0];
|
120 |
|
|
// 3'd6: dat_o <= m_w[31:16];
|
121 |
|
|
// 3'd7: dat_o <= m_w[15: 0];
|
122 |
|
|
endcase
|
123 |
|
|
else
|
124 |
|
|
dat_o <= 16'h0000;
|
125 |
|
|
|
126 |
|
|
// Register write path
|
127 |
|
|
//
|
128 |
|
|
always @(posedge clk_i)
|
129 |
|
|
if (rst_i) begin
|
130 |
|
|
m_z <= 32'h01234567; // These must be non-zero
|
131 |
|
|
m_w <= 32'h88888888;
|
132 |
|
|
end
|
133 |
|
|
else begin
|
134 |
|
|
if (cs) begin
|
135 |
|
|
if (we_i)
|
136 |
|
|
case(adr_i[3:1])
|
137 |
|
|
3'd4: m_z[31:16] <= dat_i;
|
138 |
|
|
3'd5: m_z[15: 0] <= dat_i;
|
139 |
|
|
3'd6: m_w[31:16] <= dat_i;
|
140 |
|
|
3'd7: m_w[15: 0] <= dat_i;
|
141 |
|
|
endcase
|
142 |
|
|
// cycle the generator on a read
|
143 |
|
|
else begin
|
144 |
|
|
m_z <= next_m_z;
|
145 |
|
|
m_w <= next_m_w;
|
146 |
|
|
out <= {m_z[15:0],16'd0} + m_w;
|
147 |
|
|
end
|
148 |
|
|
end
|
149 |
|
|
end
|
150 |
|
|
|
151 |
|
|
endmodule
|