ms_rand.v
6.05 KB
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/**************************************************************************
* *
* Copyright (C) 1994, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
*************************************************************************/
// $Id: ms_rand.v,v 1.1.1.1 2002/05/17 06:07:47 blythe Exp $
////////////////////////////////////////////////////////////////////////
//
// Project Reality
//
// module: ms_rand
// description: Pseudo_random number generator for mem span unit.
// Generates 3 sets of 3 bits of random numbers for
// dithering the 8 bit RGB values to 5 bits in 5/5/5/3
// color mode. Made of long period recirculating shift
// registers, with relatively prime periods within
// each color, and different periods for each of the
// nine bits. Should be run off the ungated clock, so
// will not correlate with noise in color combine unit
// which runs off the rdp's gated clock. Alpha dither
// is hashed from these random numbers and the noise
// bits for the color combine unit, which are from the
// gated clock. Therefore, alpha dither should be only
// used in the gated clock domain. Since they are
// correlated, alpha dither should not be used with
// noise.
//
// designer: Phil Gossett
// date: 10/4/94
//
////////////////////////////////////////////////////////////////////////
module ms_rand (clk, reset_l, noise, rand_r, rand_g, rand_b, alpha_dither);
input clk;
input reset_l;
input [2:0] noise; // top 3 (random) bits of cc noise[8:6]
output [2:0] rand_r;
output [2:0] rand_g;
output [2:0] rand_b;
output [7:0] alpha_dither; // hash of noise and rands
reg [29:1] rand30b; // recirculating shift register
reg [28:1] rand29b; // recirculating shift register
reg [27:1] rand28b; // recirculating shift register
reg [26:1] rand27b; // recirculating shift register
reg [25:1] rand26b; // recirculating shift register
reg [24:1] rand25b; // recirculating shift register
reg [22:1] rand23b; // recirculating shift register
reg [20:1] rand21b; // recirculating shift register
reg [18:1] rand19b; // recirculating shift register
reg rand30q; // recirculating shift register (ls bit)
reg rand29q; // recirculating shift register (ls bit)
reg rand28q; // recirculating shift register (ls bit)
reg rand27q; // recirculating shift register (ls bit)
reg rand26q; // recirculating shift register (ls bit)
reg rand25q; // recirculating shift register (ls bit)
reg rand23q; // recirculating shift register (ls bit)
reg rand21q; // recirculating shift register (ls bit)
reg rand19q; // recirculating shift register (ls bit)
reg [7:0] alpha_dither;
wire reset;
// invert reset (this week)
assign reset = ~reset_l;
// 9 bits worth of pseudo-random number generators
always @(posedge clk)
begin
// 2^30 - 1 = 1,073,741,823 = 3*3*7*11*31*151*331 = 16 s
rand30b[29:1] <= {rand30b[28:1],rand30q};
// 2^29 - 1 = 536,870,911 = 233*1103*2089 = 8 s
rand29b[28:1] <= {rand29b[27:1],rand29q};
// 2^28 - 1 = 268,435,455 = 3*5*29*43*113*127 = 4 s
rand28b[27:1] <= {rand28b[26:1],rand28q};
// 2^27 - 1 = 134,217,727 = 7*73*262657 = 2 s
rand27b[26:1] <= {rand27b[25:1],rand27q};
// 2^26 - 1 = 67,108,863 = 3*2731*8191 = 1 s
rand26b[25:1] <= {rand26b[24:1],rand26q};
// 2^25 - 1 = 33,554,431 = 31*601*1801 = 500 ms
rand25b[24:1] <= {rand25b[23:1],rand25q};
// 2^23 - 1 = 8,388,607 = 47*178481 = 125 ms
rand23b[22:1] <= {rand23b[21:1],rand23q};
// 2^21 - 1 = 2,097,151 = 7*7*127*337 = 32 ms
rand21b[20:1] <= {rand21b[19:1],rand21q};
// 2^19 - 1 = 524,287 = 524287 = 8 ms
rand19b[18:1] <= {rand19b[17:1],rand19q};
end
// 9 bits worth of pseudo-random number generators (ls bit)
always @(posedge clk or posedge reset)
begin
if (reset == 1'b1)
begin
rand30q <= 1'b1;
rand29q <= 1'b1;
rand28q <= 1'b1;
rand27q <= 1'b1;
rand26q <= 1'b1;
rand25q <= 1'b1;
rand23q <= 1'b1;
rand21q <= 1'b1;
rand19q <= 1'b1;
end
else
begin
// 2^30 - 1 = 1,073,741,823 = 3*3*7*11*31*151*331 = 16 s
rand30q <= rand30b[29]^rand30b[5]^rand30b[3]^rand30q;
// 2^29 - 1 = 536,870,911 = 233*1103*2089 = 8 s:
rand29q <= rand29b[28]^rand29b[1];
// 2^28 - 1 = 268,435,455 = 3*5*29*43*113*127 = 4 s:
rand28q <= rand28b[27]^rand28b[2];
// 2^27 - 1 = 134,217,727 = 7*73*262657 = 2 s:
rand27q <= rand27b[26]^rand27b[4]^rand27b[1]^rand27q;
// 2^26 - 1 = 67,108,863 = 3*2731*8191 = 1 s
rand26q <= rand26b[25]^rand26b[5]^rand26b[1]^rand26q;
// 2^25 - 1 = 33,554,431 = 31*601*1801 = 500 ms
rand25q <= rand25b[24]^rand25b[2];
// 2^23 - 1 = 8,388,607 = 47*178481 = 125 ms
rand23q <= rand23b[22]^rand23b[4];
// 2^21 - 1 = 2,097,151 = 7*7*127*337 = 32 ms
rand21q <= rand21b[20]^rand21b[1];
// 2^19 - 1 = 524,287 = 524287 = 8 ms
rand19q <= rand19b[18]^rand19b[4]^rand19b[1]^rand19q;
end
end
// concatenate to form dither values
assign rand_r = {rand28q,rand27q,rand25q}; // intermediate period
assign rand_g = {rand30q,rand29q,rand23q}; // longest period
assign rand_b = {rand26q,rand21q,rand19q}; // shortest period
// hash noise (gclk: q29,28,27) and rands (clk: q26,25,23,21,19)
always @(posedge clk)
begin
alpha_dither[7] <= noise[1]^noise[0];
alpha_dither[6] <= noise[0]^noise[2];
alpha_dither[5] <= noise[2]^noise[1];
alpha_dither[4] <= noise[2]^rand_b[2];
alpha_dither[3] <= noise[1]^rand_r[0];
alpha_dither[2] <= noise[0]^rand_g[0];
alpha_dither[1] <= noise[2]^rand_b[1];
alpha_dither[0] <= noise[1]^rand_b[0];
end
endmodule // ms_rand