first submit
This commit is contained in:
commit
ab2d1571bf
|
|
@ -0,0 +1,75 @@
|
|||
00100000
|
||||
00100010
|
||||
0C000004
|
||||
08000004
|
||||
10008001
|
||||
8000000a
|
||||
|
||||
00200000
|
||||
00100100
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
83828180
|
||||
87868584
|
||||
8b8a8988
|
||||
8f8e8d8c
|
||||
93929190
|
||||
97969594
|
||||
9b9a9998
|
||||
9f9e9d9c
|
||||
a3a2a1a0
|
||||
a7a6a5a4
|
||||
abaaa9a8
|
||||
afaeadac
|
||||
b3b2b1b0
|
||||
b7b6b5b4
|
||||
bbbab9b8
|
||||
bfbebdbc
|
||||
c3c2c1c0
|
||||
c7c6c5c4
|
||||
cbcac9c8
|
||||
cfcecdcc
|
||||
d3d2d1d0
|
||||
d7d6d5d4
|
||||
dbdad9d8
|
||||
dfdedddc
|
||||
e3e2e1e0
|
||||
e7e6e5e4
|
||||
ebeae9e8
|
||||
efeeedec
|
||||
f3f2f1f0
|
||||
f7f6f5f4
|
||||
fbfaf9f8
|
||||
fffefdfc
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
00100000
|
||||
0010000c
|
||||
04000004
|
||||
8000000a
|
||||
10008001
|
||||
|
||||
00200000
|
||||
00100140
|
||||
00000000
|
||||
11111111
|
||||
22222222
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
11111111
|
||||
22222222
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
00000000
|
||||
22222222
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
00000000
|
||||
11111111
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
00000000
|
||||
11111111
|
||||
22222222
|
||||
ffffffff
|
||||
eeeeeeee
|
||||
dddddddd
|
||||
cccccccc
|
||||
bbbbbbbb
|
||||
aaaaaaaa
|
||||
99999999
|
||||
88888888
|
||||
77777777
|
||||
66666666
|
||||
55555555
|
||||
44444444
|
||||
33333333
|
||||
22222222
|
||||
11111111
|
||||
12345678
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
00100000
|
||||
00100008
|
||||
04000004
|
||||
10008001
|
||||
|
||||
00200000
|
||||
00100140
|
||||
00000000
|
||||
11111111
|
||||
22222222
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
11111111
|
||||
22222222
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
00000000
|
||||
22222222
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
00000000
|
||||
11111111
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
00000000
|
||||
11111111
|
||||
22222222
|
||||
ffffffff
|
||||
eeeeeeee
|
||||
dddddddd
|
||||
cccccccc
|
||||
bbbbbbbb
|
||||
aaaaaaaa
|
||||
99999999
|
||||
88888888
|
||||
77777777
|
||||
66666666
|
||||
55555555
|
||||
44444444
|
||||
33333333
|
||||
22222222
|
||||
11111111
|
||||
12345678
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
00100000
|
||||
00100010
|
||||
04000004
|
||||
10008001
|
||||
8000000a
|
||||
8000000f
|
||||
|
||||
00200000
|
||||
00100140
|
||||
00000000
|
||||
11111111
|
||||
22222222
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
11111111
|
||||
22222222
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
00000000
|
||||
22222222
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
00000000
|
||||
11111111
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
00000000
|
||||
11111111
|
||||
22222222
|
||||
ffffffff
|
||||
eeeeeeee
|
||||
dddddddd
|
||||
cccccccc
|
||||
bbbbbbbb
|
||||
aaaaaaaa
|
||||
99999999
|
||||
88888888
|
||||
77777777
|
||||
66666666
|
||||
55555555
|
||||
44444444
|
||||
33333333
|
||||
22222222
|
||||
11111111
|
||||
12345678
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
00100000
|
||||
0010000c
|
||||
04000004
|
||||
8000000a
|
||||
00008002
|
||||
|
||||
00200000
|
||||
00100180
|
||||
00000000
|
||||
11111111
|
||||
22222222
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
11111111
|
||||
22222222
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
00000000
|
||||
22222222
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
00000000
|
||||
11111111
|
||||
33333333
|
||||
44444444
|
||||
55555555
|
||||
66666666
|
||||
77777777
|
||||
88888888
|
||||
99999999
|
||||
aaaaaaaa
|
||||
bbbbbbbb
|
||||
cccccccc
|
||||
dddddddd
|
||||
eeeeeeee
|
||||
ffffffff
|
||||
00000000
|
||||
11111111
|
||||
22222222
|
||||
ffffffff
|
||||
eeeeeeee
|
||||
dddddddd
|
||||
cccccccc
|
||||
bbbbbbbb
|
||||
aaaaaaaa
|
||||
99999999
|
||||
88888888
|
||||
77777777
|
||||
66666666
|
||||
55555555
|
||||
44444444
|
||||
33333333
|
||||
22222222
|
||||
11111111
|
||||
12345678
|
||||
ffffffff
|
||||
eeeeeeee
|
||||
dddddddd
|
||||
cccccccc
|
||||
bbbbbbbb
|
||||
aaaaaaaa
|
||||
99999999
|
||||
88888888
|
||||
77777777
|
||||
66666666
|
||||
55555555
|
||||
44444444
|
||||
33333333
|
||||
22222222
|
||||
11111111
|
||||
98765432
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
00100000
|
||||
00000004
|
||||
0c00000a
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
00100000
|
||||
0010000C
|
||||
04000001
|
||||
800003e8
|
||||
04002001
|
||||
|
||||
00200000
|
||||
00100080
|
||||
09060300
|
||||
16130f0c
|
||||
221f1c19
|
||||
2f2c2926
|
||||
3c393532
|
||||
4945423f
|
||||
55524f4c
|
||||
625f5c58
|
||||
6f6b6865
|
||||
7b787572
|
||||
8885827e
|
||||
95928e8b
|
||||
a19e9b98
|
||||
aeaba8a5
|
||||
bbb8b4b1
|
||||
c8c4c1be
|
||||
bec1c4c8
|
||||
b1b4b8bb
|
||||
a5a8abae
|
||||
989b9ea1
|
||||
8b8e9295
|
||||
7e828588
|
||||
7275787b
|
||||
65686b6f
|
||||
585c5f62
|
||||
4c4f5255
|
||||
3f424549
|
||||
3235393c
|
||||
26292c2f
|
||||
191c1f22
|
||||
0c0f1316
|
||||
00030609
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
bcbcbcbc
|
||||
12340020
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
81808080
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
82828281
|
||||
82828282
|
||||
82828282
|
||||
82828282
|
||||
82828282
|
||||
82828282
|
||||
82828282
|
||||
2afef1eb
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
00100000
|
||||
00000004
|
||||
04000002
|
||||
00200000
|
||||
00000080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
80808080
|
||||
81808080
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
81818181
|
||||
82828281
|
||||
82828282
|
||||
82828282
|
||||
82828282
|
||||
82828282
|
||||
82828282
|
||||
82828282
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
bcbcbcbc
|
||||
000000a0
|
||||
b9a79380
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c80
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
b9a7937f
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c80
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
b9a7937f
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c80
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
b9a7937f
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c80
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
b9a7937f
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c80
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
b9a7937f
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c7f
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
b9a7937f
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c80
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
b9a7937f
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c80
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
b9a7937f
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c7f
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
b9a7937f
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c7f
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
b9a7937f
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c7f
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
b9a79380
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c7f
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
b9a7937f
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c80
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
b9a7937f
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c80
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
b9a7937f
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c80
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
b9a7937f
|
||||
f1e6d9ca
|
||||
fdfffdf8
|
||||
d9e6f1f8
|
||||
93a7b9ca
|
||||
46586c80
|
||||
0e192635
|
||||
02010207
|
||||
26190e07
|
||||
6c584635
|
||||
17738bd1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,30 @@
|
|||
module DEM_Reverse (
|
||||
input clk, // 时钟输入
|
||||
input [6:0] therm_in, // 7位温度计码输入 (MSB部分)
|
||||
input [4:0] bin_in, // 5位二进制码输入 (LSB部分)
|
||||
output reg [7:0] data_out // 恢复的8位DAC输入
|
||||
);
|
||||
|
||||
// 统计温度计码中1的个数(权重总和)
|
||||
function [2:0] count_ones;
|
||||
input [6:0] data;
|
||||
integer i;
|
||||
begin
|
||||
count_ones = 0;
|
||||
for (i = 0; i < 7; i = i + 1) begin
|
||||
if (data[i]) count_ones = count_ones + 1;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
// 组合逻辑计算中间值
|
||||
wire [2:0] msb_value = count_ones(therm_in);
|
||||
wire [4:0] lsb_value = bin_in;
|
||||
wire [7:0] data_comb = {msb_value, lsb_value};
|
||||
|
||||
// 在时钟上升沿寄存输出
|
||||
always @(posedge clk) begin
|
||||
data_out <= data_comb;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
module DEM_Reverse_64CH (
|
||||
input clk
|
||||
,input [6:0] msb_in [63:0]
|
||||
,input [4:0] lsb_in [63:0]
|
||||
,input vld_in
|
||||
,output reg vld_out
|
||||
,output reg [7:0] data_out [63:0]
|
||||
);
|
||||
|
||||
reg [7:0] data_out_rr[63:0];
|
||||
reg [7:0] data_out_r [63:0];
|
||||
reg [1:0] vld_out_r;
|
||||
genvar k;
|
||||
generate
|
||||
|
||||
for(k = 0; k < 32; k = k + 1) begin
|
||||
DEM_Reverse U_DEM_Reverse (
|
||||
.clk ( clk )
|
||||
,.therm_in ( msb_in[k] )
|
||||
,.bin_in ( lsb_in[k] )
|
||||
,.data_out ( data_out_r[k] )
|
||||
);
|
||||
|
||||
end
|
||||
|
||||
for(k = 32; k < 64; k = k + 1) begin
|
||||
DEM_Reverse U_DEM_Reverse (
|
||||
.clk ( ~clk )
|
||||
,.therm_in ( msb_in[k] )
|
||||
,.bin_in ( lsb_in[k] )
|
||||
,.data_out ( data_out_r[k] )
|
||||
);
|
||||
|
||||
end
|
||||
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
|
||||
for(k = 0; k < 64; k = k + 1) begin
|
||||
if(k<32) begin
|
||||
assign data_out[k] = data_out_r[k];
|
||||
end
|
||||
else begin
|
||||
assign data_out[k] = data_out_rr[k];
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
endgenerate
|
||||
|
||||
|
||||
always @(posedge clk) begin
|
||||
data_out_rr <= data_out_r;
|
||||
end
|
||||
|
||||
// \u5728\u65f6\u949f\u4e0a\u5347\u6cbf\u5bc4\u5b58\u8f93\u51fa
|
||||
always @(posedge clk) begin
|
||||
vld_out_r <= {vld_out_r[0],vld_in};
|
||||
end
|
||||
|
||||
assign vld_out = vld_out_r[1];
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,301 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This confidential and proprietary software may be used only
|
||||
// as authorized by a licensing agreement from Synopsys Inc.
|
||||
// In the event of publication, the following notice is applicable:
|
||||
//
|
||||
// (C) COPYRIGHT 2004 - 2018 SYNOPSYS INC.
|
||||
// ALL RIGHTS RESERVED
|
||||
//
|
||||
// The entire notice above must be reproduced on all authorized
|
||||
// copies.
|
||||
//
|
||||
// AUTHOR: bruce dean June 26th. 2004
|
||||
//
|
||||
// VERSION: Simulation model
|
||||
//
|
||||
// DesignWare_version: 0d24140b
|
||||
// DesignWare_release: O-2018.06-DWBB_201806.1
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//----------------------------------------------------------------------------
|
||||
// ABSTRACT: Generic pulse sychronization block
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Parameters: Valid Values
|
||||
// ========== ============
|
||||
// reg_event [ 0 => event_d will have combination logic
|
||||
// but latency will be 1 cycle sooner
|
||||
// 1 => event_d will be retimed so there will
|
||||
// be no logic between register & port
|
||||
// but event is delayed 1 cycle]
|
||||
// f_sync_type [ 0 = single clock design, no synchronizing stages implemented,
|
||||
// 1 = 2-stage synchronization w/ 1st stage neg-edge & 2nd stage pos-edge capturing,
|
||||
// 2 = 2-stage synchronization w/ both stages pos-edge capturing,
|
||||
// 3 = 3-stage synchronization w/ all stages pos-edge capturing ]
|
||||
// 4 = 4-stage synchronization w/ all stages pos-edge capturing ]
|
||||
// tst_mode [ 0 = no hold latch inserted,
|
||||
// 1 = insert hold 'latch' using a neg-edge triggered register
|
||||
// 2 = insert active-low hold latch ]
|
||||
// verif_en [ 0 = no sampling errors inserted,
|
||||
// 1 = sampling errors are randomly inserted with 0 or up to 1 destination clock cycle delays
|
||||
// 2 = sampling errors are randomly inserted with 0, 0.5, 1, or 1.5 destination clock cycle delays
|
||||
// 3 = sampling errors are randomly inserted with 0, 1, 2, or 3 destination clock cycle delays
|
||||
// 4 = sampling errors are randomly inserted with 0 or up to 0.5 destination clock cycle delays ]
|
||||
// pulse_mode [ 0 => single clock cycle pulse in produces
|
||||
// single clock cycle pulse out
|
||||
// 1 => rising edge transition in produces
|
||||
// 2 => falling edge transition in produces
|
||||
// single clock cycle pulse out
|
||||
// 3 => toggle transition in produces
|
||||
// single clock cycle pulse out]
|
||||
///
|
||||
// Input Ports: Size Description
|
||||
// =========== ==== ===========
|
||||
// clk_s 1 bit Source Domain Input Clock
|
||||
// rst_s_n 1 bit Source Domain Active Low Async. Reset
|
||||
// init_s_n 1 bit Source Domain Active Low Sync. Reset
|
||||
// send_s 1 bit Source Domain Active High Send Request
|
||||
// data_s N bits Source Domain Data Input
|
||||
// clk_d 1 bit Destination Domain Input Clock
|
||||
// rst_d_n 1 bit Destination Domain Active Low Async. Reset
|
||||
// init_d_n 1 bit Destination Domain Active Low Sync. Reset
|
||||
// test 1 bit Test input
|
||||
//
|
||||
// Output Ports Size Description
|
||||
// ============ ==== ===========
|
||||
// event_d 1 bit Dest Domain Active High Event Signal
|
||||
//
|
||||
// MODIFIED:
|
||||
//
|
||||
// RJK 3-08-17 Corrected port order to be consistent with synthesis
|
||||
//
|
||||
// DLL 9-21-11 Added tst_mode=2 checking and comments (not a functional change)
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
module DW_pulse_sync
|
||||
(
|
||||
clk_s,
|
||||
rst_s_n,
|
||||
init_s_n,
|
||||
event_s,
|
||||
clk_d,
|
||||
rst_d_n,
|
||||
init_d_n,
|
||||
event_d,
|
||||
test
|
||||
);
|
||||
parameter integer reg_event = 0; // 0 => event_d will have combination logic
|
||||
// but latency will be 1 cycle sooner
|
||||
// 1 => event_d will be retimed so there will
|
||||
// be no logic between register & port
|
||||
// but event is delayed 1 cycle
|
||||
|
||||
parameter integer f_sync_type = 1; // 0 - 3
|
||||
// 0 => single clock design, i.e. clk_d == clk_s
|
||||
// 1 => first synchronization in clk_d domain is
|
||||
// done on the negative edge and the rest
|
||||
// on positive edge. This reduces latency
|
||||
// req. of synchronization slightly but
|
||||
// quicker metastability resolution for
|
||||
// the negative edge sensitive FF. It also
|
||||
// requires the technology library to
|
||||
// contain an acceptable negative edge
|
||||
// sensitive FF.
|
||||
// 2 => all synchronization in clk_d domain is
|
||||
// done on positive edges - 2 d flops in
|
||||
// destination domain
|
||||
// 3 => all synchronization in clk_d domain is
|
||||
// done on positive edges - 3 d flops in
|
||||
// destination domain
|
||||
// 4 => all synchronization in clk_d domain is
|
||||
// done on positive edges - 4 d flops in
|
||||
// destination domain
|
||||
parameter integer tst_mode = 0; // 0-2
|
||||
// 0 => no latch insertion
|
||||
// 1 => hold latch using neg edge flop
|
||||
// 2 => reserved unsupported
|
||||
|
||||
parameter integer verif_en = 1; // 0-4
|
||||
// 0 => no sampling errors are used
|
||||
// 1 => random insertion of 0 or upt to 1 dest clk
|
||||
// 2 => random insertion of 0,0.5,1,or 1.5 dest clk
|
||||
// 3 => random insertion of 0,1,2,or 3 dest clk
|
||||
// 4 => random insertion of 0 or up to 0.5 dest clk
|
||||
parameter integer pulse_mode = 0; // 0 => single clock cycle pulse in produces
|
||||
// single clock cycle pulse out
|
||||
// 1 => rising edge transition in produces
|
||||
// 2 => falling edge transition in produces
|
||||
// single clock cycle pulse out
|
||||
// 3 => toggle transition in produces
|
||||
// single clock cycle pulse out
|
||||
|
||||
input clk_s; // clock input for source domain
|
||||
input rst_s_n; // active low async. reset in clk_s domain
|
||||
input init_s_n; // active low sync. reset in clk_s domain
|
||||
input event_s; // event pulse input (active high event)
|
||||
input clk_d; // clock input for destination domain
|
||||
input rst_d_n; // active low async. reset in clk_d domain
|
||||
input init_d_n; // active low sync. reset in clk_d domain
|
||||
output event_d; // event pulse output (active high event)
|
||||
input test; // test 1 bit Test input
|
||||
|
||||
initial begin
|
||||
if ((f_sync_type > 0)&&(f_sync_type < 8))
|
||||
$display("Information: *** Instance %m is the DW_pulse_sync Clock Domain Crossing Module ***");
|
||||
end
|
||||
|
||||
// synopsys translate_off
|
||||
// Param check
|
||||
|
||||
|
||||
initial begin : parameter_check
|
||||
integer param_err_flg;
|
||||
|
||||
param_err_flg = 0;
|
||||
|
||||
|
||||
if ( (reg_event < 0) || (reg_event > 1) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter reg_event (legal range: 0 to 1)",
|
||||
reg_event );
|
||||
end
|
||||
|
||||
if ( ((f_sync_type & 7) < 0) || ((f_sync_type & 7) > 4) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter (f_sync_type & 7) (legal range: 0 to 4)",
|
||||
(f_sync_type & 7) );
|
||||
end
|
||||
|
||||
if ( (tst_mode < 0) || (tst_mode > 2) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter tst_mode (legal range: 0 to 2)",
|
||||
tst_mode );
|
||||
end
|
||||
|
||||
if ( (verif_en < 0) || (verif_en > 4) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter verif_en (legal range: 0 to 4)",
|
||||
verif_en );
|
||||
end
|
||||
|
||||
if ( (pulse_mode < 0) || (pulse_mode > 3) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter pulse_mode (legal range: 0 to 3)",
|
||||
pulse_mode );
|
||||
end
|
||||
|
||||
if ( param_err_flg == 1) begin
|
||||
$display(
|
||||
"%m :\n Simulation aborted due to invalid parameter value(s)");
|
||||
$finish;
|
||||
end
|
||||
|
||||
end // parameter_check
|
||||
|
||||
wire O0I100OO;
|
||||
reg O1O10OI0;
|
||||
reg OO10OI10;
|
||||
reg [1:0] O0OlIO00;
|
||||
wire II1lIlI0;
|
||||
reg OOO01l10;
|
||||
reg O00O000l;
|
||||
wire O101lOO0;
|
||||
|
||||
|
||||
generate
|
||||
if (((f_sync_type&7)>1)&&(tst_mode==2)) begin : GEN_LATCH_frwd_hold_latch_PROC
|
||||
reg [1-1:0] OO10OI10;
|
||||
always @ (clk_s or O1O10OI0) begin : LATCH_frwd_hold_latch_PROC_PROC
|
||||
|
||||
if (clk_s == 1'b0)
|
||||
|
||||
OO10OI10 = O1O10OI0;
|
||||
|
||||
|
||||
end // LATCH_frwd_hold_latch_PROC_PROC
|
||||
|
||||
|
||||
assign O0I100OO = (test==1'b1)? OO10OI10 : O1O10OI0;
|
||||
|
||||
end else begin : GEN_DIRECT_frwd_hold_latch_PROC
|
||||
assign O0I100OO = O1O10OI0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
DW_sync #(1, f_sync_type+8, tst_mode, verif_en) SIM(
|
||||
.clk_d(clk_d),
|
||||
.rst_d_n(rst_d_n),
|
||||
.init_d_n(init_d_n),
|
||||
.data_s(O0I100OO),
|
||||
.test(test),
|
||||
.data_d(II1lIlI0) );
|
||||
assign O101lOO0 = pulse_mode === 0 ? event_s ^ O1O10OI0
|
||||
:(pulse_mode === 1? (event_s & ! O00O000l) ^ O1O10OI0
|
||||
:(pulse_mode === 2? (!event_s & O00O000l) ^ O1O10OI0
|
||||
:(pulse_mode === 3? (event_s ^ O00O000l) ^ O1O10OI0: 1'bx)));
|
||||
always @ ( posedge clk_s or negedge rst_s_n ) begin : a1000_PROC
|
||||
if(rst_s_n === 1'b0 ) begin
|
||||
O1O10OI0 <= 1'b0;
|
||||
O00O000l <= 1'b0;
|
||||
end else if(rst_s_n === 1'b1 ) begin
|
||||
if(init_s_n === 1'b0 ) begin
|
||||
O1O10OI0 <= 1'b0;
|
||||
O00O000l <= 1'b0;
|
||||
end else if(init_s_n === 1'b1 ) begin
|
||||
if(event_s === 1'b1) begin
|
||||
O1O10OI0 <= O101lOO0;
|
||||
O00O000l <= event_s;
|
||||
end else if(event_s !== 1'b0) begin
|
||||
O1O10OI0 <= 1'bx;
|
||||
O00O000l <= 1'bx;
|
||||
end else begin
|
||||
O1O10OI0 <= O101lOO0;
|
||||
O00O000l <= event_s;
|
||||
end
|
||||
end else begin
|
||||
O1O10OI0 <= 1'bx;
|
||||
O00O000l <= 1'bx;
|
||||
end
|
||||
end else begin
|
||||
O1O10OI0 <= 1'bx;
|
||||
O00O000l <= 1'bx;
|
||||
end
|
||||
end
|
||||
always @ ( posedge clk_d or negedge rst_d_n) begin : a1001_PROC
|
||||
if(rst_d_n === 1'b0 )
|
||||
O0OlIO00 <= 2'b00;
|
||||
else if(rst_d_n === 1'b1 )
|
||||
if(init_d_n === 1'b0)
|
||||
O0OlIO00 <= 2'b00;
|
||||
else if(init_d_n === 1'b1)
|
||||
O0OlIO00 <= {O0OlIO00[0] ^ II1lIlI0, II1lIlI0};
|
||||
else
|
||||
O0OlIO00 <= 2'bxx;
|
||||
else
|
||||
O0OlIO00 <= 2'bxx;
|
||||
end
|
||||
assign event_d = (reg_event) ? O0OlIO00[1] : O0OlIO00[0] ^ II1lIlI0 ;
|
||||
|
||||
always @ (clk_d) begin : monitor_clk_d
|
||||
if ( (clk_d !== 1'b0) && (clk_d !== 1'b1) && ($time > 0) )
|
||||
$display( "WARNING: %m :\n at time = %t, detected unknown value, %b, on clk_d input.",
|
||||
$time, clk_d );
|
||||
end // monitor_clk_d
|
||||
|
||||
always @ (clk_s) begin : monitor_clk_s
|
||||
if ( (clk_s !== 1'b0) && (clk_s !== 1'b1) && ($time > 0) )
|
||||
$display( "WARNING: %m :\n at time = %t, detected unknown value, %b, on clk_s input.",
|
||||
$time, clk_s );
|
||||
end // monitor_clk_s
|
||||
// synopsys translate_on
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,547 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This confidential and proprietary software may be used only
|
||||
// as authorized by a licensing agreement from Synopsys Inc.
|
||||
// In the event of publication, the following notice is applicable:
|
||||
//
|
||||
// (C) COPYRIGHT 2005 - 2018 SYNOPSYS INC.
|
||||
// ALL RIGHTS RESERVED
|
||||
//
|
||||
// The entire notice above must be reproduced on all authorized
|
||||
// copies.
|
||||
//
|
||||
// AUTHOR: Doug Lee 12/7/05
|
||||
//
|
||||
// VERSION: Simulation Architecture
|
||||
//
|
||||
// DesignWare_version: b7a01861
|
||||
// DesignWare_release: O-2018.06-DWBB_201806.1
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ABSTRACT: Reset Sequence Synchronizer Simulation Model
|
||||
//
|
||||
//
|
||||
// This synchronizer coordinates reset to the source and destination domains which initiated by
|
||||
// either domain.
|
||||
//
|
||||
// Parameters: Valid Values
|
||||
// ========== ============
|
||||
// f_sync_type default: 2
|
||||
// Forward Synchronized Type (Source to Destination Domains)
|
||||
// 0 = single clock design, no synchronizing stages implemented,
|
||||
// 1 = 2-stage synchronization w/ 1st stage neg-edge & 2nd stage pos-edge capturing,
|
||||
// 2 = 2-stage synchronization w/ both stages pos-edge capturing,
|
||||
// 3 = 3-stage synchronization w/ all stages pos-edge capturing
|
||||
// 4 = 4-stage synchronization w/ all stages pos-edge capturing
|
||||
// r_sync_type default: 2
|
||||
// Reverse Synchronization Type (Destination to Source Domains)
|
||||
// 0 = single clock design, no synchronizing stages implemented,
|
||||
// 1 = 2-stage synchronization w/ 1st stage neg-edge & 2nd stage pos-edge capturing,
|
||||
// 2 = 2-stage synchronization w/ both stages pos-edge capturing,
|
||||
// 3 = 3-stage synchronization w/ all stages pos-edge capturing
|
||||
// 4 = 4-stage synchronization w/ all stages pos-edge capturing
|
||||
// clk_d_faster default: 1
|
||||
// clk_d faster than clk_s by difference ratio
|
||||
// 0 = Either clr_s or clr_d active with the other tied low at input
|
||||
// 1 to 15 = ratio of clk_d to clk_s plus 1
|
||||
// reg_in_prog default: 1
|
||||
// Register the 'clr_in_prog_s' and 'clr_in_prog_d' Outputs
|
||||
// 0 = unregistered
|
||||
// 1 = registered
|
||||
// tst_mode default: 0
|
||||
// Test Mode Setting
|
||||
// 0 = no hold latch inserted,
|
||||
// 1 = insert hold 'latch' using a neg-edge triggered register
|
||||
// 2 = insert hold latch using active low latch
|
||||
// verif_en default: 1
|
||||
// Verification Enable (simulation only)
|
||||
// 0 = no sampling errors inserted,
|
||||
// 1 = sampling errors are randomly inserted with 0 or up to 1 destination clock cycle delays
|
||||
// 2 = sampling errors are randomly inserted with 0, 0.5, 1, or 1.5 destination clock cycle delays
|
||||
// 3 = sampling errors are randomly inserted with 0, 1, 2, or 3 destination clock cycle delays
|
||||
// 4 = sampling errors are randomly inserted with 0 or up to 0.5 destination clock cycle delays
|
||||
//
|
||||
// Input Ports: Size Description
|
||||
// =========== ==== ===========
|
||||
// clk_s 1 bit Source Domain Input Clock
|
||||
// rst_s_n 1 bit Source Domain Active Low Async. Reset
|
||||
// init_s_n 1 bit Source Domain Active Low Sync. Reset
|
||||
// clr_s 1 bit Source Domain Clear Initiated
|
||||
// clk_d 1 bit Destination Domain Input Clock
|
||||
// rst_d_n 1 bit Destination Domain Active Low Async. Reset
|
||||
// init_d_n 1 bit Destination Domain Active Low Sync. Reset
|
||||
// clr_d 1 bit Destination Domain Clear Initiated
|
||||
// test 1 bit Test input
|
||||
//
|
||||
// Output Ports Size Description
|
||||
// ============ ==== ===========
|
||||
// clr_sync_s 1 bit Source Domain Clear
|
||||
// clr_in_prog_s 1 bit Source Domain Clear in Progress
|
||||
// clr_cmplt_s 1 bit Source Domain Clear Complete (pulse)
|
||||
// clr_in_prog_d 1 bit Destination Domain Clear in Progress
|
||||
// clr_sync_d 1 bit Destination Domain Clear (pulse)
|
||||
// clr_cmplt_d 1 bit Destination Domain Clear Complete (pulse)
|
||||
//
|
||||
// MODIFIED:
|
||||
// DLL 5-7-15 (1) Restricted the amount of missampling allowed for DW_pulse_sync
|
||||
// U_PS_DEST_INIT to make delay more realistic.
|
||||
// (2) Changed 'reg_event' from '1' to '0' for instance U_PS_DEST_INIT
|
||||
// to allow 'clr_in_prog_s' to occur one cycle earlier that
|
||||
// helps prevent a race condition on signals syncrhonized back
|
||||
// to the source domain.
|
||||
// Addresses fix for STAR#9000896107 (filed against DW_fifoctl_2c_df but
|
||||
// is really a DW_reset_sync issue).
|
||||
//
|
||||
// DLL 7-22-11 Add inherent delay to the feedback path in the destination
|
||||
// domain and clr_in_prog_d. This effectively extends the
|
||||
// destination domain acive clearing state.
|
||||
// Also, added 'tst_mode = 2' capability.
|
||||
//
|
||||
// DLL 12-2-10 Removed assertions since only ones left were not
|
||||
// relevant any more. This fix is by-product of investigating
|
||||
// STAR#9000435571.
|
||||
//
|
||||
// DLL 9-5-08 Accommodate sustained "clr_s" and "clr_d" assertion behavior.
|
||||
// Satisfies STAR#9000261751.
|
||||
//
|
||||
// DLL 8-11-08 Filter long pulses of "clr_s" and "clr_d" to one
|
||||
// clock cycle pulses.
|
||||
//
|
||||
// DLL 10-31-06 Added SystemVerilog assertions
|
||||
//
|
||||
// DLL 8-21-06 Added parameters 'r_sync_type', 'clk_d_faster', 'reg_in_prog'.
|
||||
// Added Destination outputs 'clr_in_prog_d' and 'clr_cmplt_d'
|
||||
// and changed Source output 'lO1O1011' to 'clr_cmplt_s'.
|
||||
//
|
||||
// DLL 6-14-06 Removed unnecessary To_X01 processing some input signals
|
||||
//
|
||||
// DLL 11-7-06 Modified functionality to support f_sync_type = 4 and
|
||||
// r_sync_type = 4
|
||||
//
|
||||
module DW_reset_sync (
|
||||
clk_s,
|
||||
rst_s_n,
|
||||
init_s_n,
|
||||
clr_s,
|
||||
clr_sync_s,
|
||||
clr_in_prog_s,
|
||||
clr_cmplt_s,
|
||||
|
||||
clk_d,
|
||||
rst_d_n,
|
||||
init_d_n,
|
||||
clr_d,
|
||||
clr_in_prog_d,
|
||||
clr_sync_d,
|
||||
clr_cmplt_d,
|
||||
|
||||
test
|
||||
);
|
||||
|
||||
parameter integer f_sync_type = 2; // RANGE 0 to 4
|
||||
parameter integer r_sync_type = 2; // RANGE 0 to 4
|
||||
parameter integer clk_d_faster = 1; // RANGE 0 to 15
|
||||
parameter integer reg_in_prog = 1; // RANGE 0 to 1
|
||||
parameter integer tst_mode = 0; // RANGE 0 to 2
|
||||
parameter integer verif_en = 1; // RANGE 0 to 4
|
||||
|
||||
`define DW_IIOOl10O 2
|
||||
|
||||
localparam O0llO1Ol = ((verif_en==2)?4:((verif_en==3)?1:verif_en));
|
||||
|
||||
|
||||
input clk_s; // clock input from source domain
|
||||
input rst_s_n; // active low asynchronous reset from source domain
|
||||
input init_s_n; // active low synchronous reset from source domain
|
||||
input clr_s; // active high clear from source domain
|
||||
output clr_sync_s; // clear to source domain sequential devices
|
||||
output clr_in_prog_s; // clear in progress status to source domain
|
||||
output clr_cmplt_s; // clear sequence complete (pulse)
|
||||
|
||||
input clk_d; // clock input from destination domain
|
||||
input rst_d_n; // active low asynchronous reset from destination domain
|
||||
input init_d_n; // active low synchronous reset from destination domain
|
||||
input clr_d; // active high clear from destination domain
|
||||
output clr_in_prog_d; // clear in progress status to source domain
|
||||
output clr_sync_d; // clear to destination domain sequential devices (pulse)
|
||||
output clr_cmplt_d; // clear sequence complete (pulse)
|
||||
|
||||
input test; // test input
|
||||
|
||||
// synopsys translate_off
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Parameter legality check
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
|
||||
initial begin : parameter_check
|
||||
integer param_err_flg;
|
||||
|
||||
param_err_flg = 0;
|
||||
|
||||
|
||||
if ( ((f_sync_type & 7) < 0) || ((f_sync_type & 7) > 4) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter (f_sync_type & 7) (legal range: 0 to 4)",
|
||||
(f_sync_type & 7) );
|
||||
end
|
||||
|
||||
if ( ((r_sync_type & 7) < 0) || ((r_sync_type & 7) > 4) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter (r_sync_type & 7) (legal range: 0 to 4)",
|
||||
(r_sync_type & 7) );
|
||||
end
|
||||
|
||||
if ( (reg_in_prog < 0) || (reg_in_prog > 1) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter reg_in_prog (legal range: 0 to 1)",
|
||||
reg_in_prog );
|
||||
end
|
||||
|
||||
if ( (tst_mode < 0) || (tst_mode > 2) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter tst_mode (legal range: 0 to 2)",
|
||||
tst_mode );
|
||||
end
|
||||
|
||||
if ( (verif_en < 0) || (verif_en > 4) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter verif_en (legal range: 0 to 4)",
|
||||
verif_en );
|
||||
end
|
||||
|
||||
if ( param_err_flg == 1) begin
|
||||
$display(
|
||||
"%m :\n Simulation aborted due to invalid parameter value(s)");
|
||||
$finish;
|
||||
end
|
||||
|
||||
end // parameter_check
|
||||
|
||||
|
||||
wire lOl0I0l1;
|
||||
wire Il0110O1;
|
||||
wire O010111l;
|
||||
|
||||
integer I01O0111;
|
||||
integer l1010110;
|
||||
|
||||
reg O1111O0O;
|
||||
wire OOlIO1OO;
|
||||
reg lll0OO11;
|
||||
wire I0I0O1l1;
|
||||
wire lO1O1011;
|
||||
|
||||
reg l011lO0l;
|
||||
wire l00O0lO1;
|
||||
wire l11Ol01I;
|
||||
wire OI01IO11;
|
||||
wire l0Ol100I;
|
||||
reg l10Ol00O;
|
||||
|
||||
wire IOIOOIlO;
|
||||
wire OOI1001O;
|
||||
|
||||
reg O100OIlI;
|
||||
wire l0IlI00O;
|
||||
reg IIOOI0Ol;
|
||||
reg Il1O110I;
|
||||
reg O1OOO1O0;
|
||||
wire O0OIl111;
|
||||
|
||||
integer OOOOIlO1;
|
||||
integer OI1IO11l;
|
||||
|
||||
reg OlOOO000;
|
||||
wire IllIlOl0;
|
||||
wire I0OO1l01;
|
||||
wire lI1IO1O0;
|
||||
reg OO001I10;
|
||||
|
||||
wire O0III10l;
|
||||
reg IO00llI0;
|
||||
|
||||
wire OOlOO11O;
|
||||
reg OIO10I11;
|
||||
|
||||
integer O0IOO0OO;
|
||||
|
||||
|
||||
|
||||
assign IllIlOl0 = (reg_in_prog == 0) ? ((IOIOOIlO && !OlOOO000) ||
|
||||
(((OI1IO11l == 1) && (OOOOIlO1 == 0)) && IOIOOIlO)) :
|
||||
// (!clr_in_prog_d && IOIOOIlO);
|
||||
(OI1IO11l == 1) && (OOOOIlO1 == 0);
|
||||
assign I0OO1l01 = (OI1IO11l == 0) && (OOOOIlO1 == 1);
|
||||
assign lI1IO1O0 = (IllIlOl0 && !I0OO1l01) ? 1'b1 :
|
||||
(I0OO1l01) ? 1'b0 : OO001I10;
|
||||
|
||||
|
||||
|
||||
initial begin
|
||||
if ((f_sync_type > 0)&&(f_sync_type < 8))
|
||||
$display("Information: *** Instance %m is the DW_reset_sync Clock Domain Crossing Module ***");
|
||||
end
|
||||
|
||||
|
||||
DW_pulse_sync #(1, (f_sync_type + 8), tst_mode, verif_en, 1) U_PS_SRC_INIT (
|
||||
.clk_s(clk_s),
|
||||
.rst_s_n(rst_s_n),
|
||||
.init_s_n(init_s_n),
|
||||
.event_s(clr_s),
|
||||
.clk_d(clk_d),
|
||||
.rst_d_n(rst_d_n),
|
||||
.init_d_n(init_d_n),
|
||||
.test(test),
|
||||
.event_d(lOl0I0l1)
|
||||
);
|
||||
|
||||
|
||||
|
||||
generate
|
||||
if (((f_sync_type&7)>1)&&(tst_mode==2)) begin : GEN_LATCH_frwd_hold_latch_PROC
|
||||
reg [1-1:0] OIO10I11;
|
||||
always @ (clk_s or clr_s) begin : LATCH_frwd_hold_latch_PROC_PROC
|
||||
|
||||
if (clk_s == 1'b0)
|
||||
|
||||
OIO10I11 = clr_s;
|
||||
|
||||
|
||||
end // LATCH_frwd_hold_latch_PROC_PROC
|
||||
|
||||
|
||||
assign OOlOO11O = (test==1'b1)? OIO10I11 : clr_s;
|
||||
|
||||
end else begin : GEN_DIRECT_frwd_hold_latch_PROC
|
||||
assign OOlOO11O = clr_s;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
DW_sync #(1, f_sync_type+8, tst_mode, verif_en) U_SYNC_CLR_S(
|
||||
.clk_d(clk_d),
|
||||
.rst_d_n(rst_d_n),
|
||||
.init_d_n(init_d_n),
|
||||
.data_s(OOlOO11O),
|
||||
.test(test),
|
||||
.data_d(Il0110O1) );
|
||||
|
||||
assign O010111l = lOl0I0l1 || Il0110O1;
|
||||
|
||||
|
||||
|
||||
DW_pulse_sync #(0, (r_sync_type + 8), tst_mode, O0llO1Ol, 0) U_PS_DEST_INIT (
|
||||
.clk_s(clk_d),
|
||||
.rst_s_n(rst_d_n),
|
||||
.init_s_n(init_d_n),
|
||||
.event_s(OOI1001O),
|
||||
.clk_d(clk_s),
|
||||
.rst_d_n(rst_s_n),
|
||||
.init_d_n(init_s_n),
|
||||
.test(test),
|
||||
.event_d(OI01IO11)
|
||||
);
|
||||
|
||||
DW_pulse_sync #(0, (f_sync_type + 8), tst_mode, verif_en, 0) U_PS_FB_DEST (
|
||||
.clk_s(clk_s),
|
||||
.rst_s_n(rst_s_n),
|
||||
.init_s_n(init_s_n),
|
||||
.event_s(l10Ol00O),
|
||||
.clk_d(clk_d),
|
||||
.rst_d_n(rst_d_n),
|
||||
.init_d_n(init_d_n),
|
||||
.test(test),
|
||||
.event_d(l11Ol01I)
|
||||
);
|
||||
|
||||
assign O0III10l = (l11Ol01I && IOIOOIlO) ? 1'b1 :
|
||||
(!l11Ol01I && !IOIOOIlO && IO00llI0) ? 1'b0 :
|
||||
IO00llI0;
|
||||
assign l00O0lO1 = (l11Ol01I && !IOIOOIlO && !IO00llI0) ||
|
||||
(!l11Ol01I && !IOIOOIlO && IO00llI0);
|
||||
|
||||
DW_pulse_sync #(0, (r_sync_type + 8), tst_mode, verif_en, 0) U_PS_ACK (
|
||||
.clk_s(clk_d),
|
||||
.rst_s_n(rst_d_n),
|
||||
.init_s_n(init_d_n),
|
||||
.event_s(l011lO0l),
|
||||
.clk_d(clk_s),
|
||||
.rst_d_n(rst_s_n),
|
||||
.init_d_n(init_s_n),
|
||||
.test(test),
|
||||
.event_d(lO1O1011)
|
||||
);
|
||||
|
||||
always @(OI01IO11 or lO1O1011 or I01O0111) begin : a1000_PROC
|
||||
if (OI01IO11 && ~lO1O1011) begin
|
||||
if (I01O0111 === `DW_IIOOl10O)
|
||||
l1010110 = I01O0111;
|
||||
else
|
||||
l1010110 = I01O0111 + 1;
|
||||
end else if (~OI01IO11 && lO1O1011) begin
|
||||
if (I01O0111 === 0)
|
||||
l1010110 = I01O0111;
|
||||
else
|
||||
l1010110 = I01O0111 - 1;
|
||||
end else begin
|
||||
l1010110 = I01O0111;
|
||||
end
|
||||
end
|
||||
|
||||
assign OOlIO1OO = (l1010110 > 0);
|
||||
|
||||
assign I0I0O1l1 = lO1O1011 && ((I01O0111 === 1) && (l1010110 === 0));
|
||||
|
||||
assign IOIOOIlO = O010111l || clr_d;
|
||||
assign OOI1001O = IOIOOIlO && !OO001I10;
|
||||
|
||||
assign l0IlI00O = (OI1IO11l > 0);
|
||||
|
||||
assign l0Ol100I = l00O0lO1 & ~OOI1001O;
|
||||
|
||||
|
||||
always @(OOI1001O or l011lO0l or OOOOIlO1) begin : a1001_PROC
|
||||
if (OOI1001O && ~l011lO0l) begin
|
||||
if (OOOOIlO1 === `DW_IIOOl10O)
|
||||
OI1IO11l = OOOOIlO1;
|
||||
else
|
||||
OI1IO11l = OOOOIlO1 + 1;
|
||||
end else if (~OOI1001O && l011lO0l) begin
|
||||
if (OOOOIlO1 === 0)
|
||||
OI1IO11l = OOOOIlO1;
|
||||
else
|
||||
OI1IO11l = OOOOIlO1 - 1;
|
||||
end else begin
|
||||
OI1IO11l = OOOOIlO1;
|
||||
end
|
||||
end
|
||||
|
||||
assign O0OIl111 = ~O100OIlI && IIOOI0Ol;
|
||||
|
||||
|
||||
always @(posedge clk_s or negedge rst_s_n) begin : a1002_PROC
|
||||
if (rst_s_n === 1'b0) begin
|
||||
I01O0111 <= 0;
|
||||
l10Ol00O <= 1'b0;
|
||||
O1111O0O <= 1'b0;
|
||||
lll0OO11 <= 1'b0;
|
||||
end else if (rst_s_n === 1'b1) begin
|
||||
if (init_s_n === 1'b0) begin
|
||||
I01O0111 <= 0;
|
||||
l10Ol00O <= 1'b0;
|
||||
O1111O0O <= 1'b0;
|
||||
lll0OO11 <= 1'b0;
|
||||
end else if (init_s_n === 1'b1) begin
|
||||
I01O0111 <= l1010110;
|
||||
l10Ol00O <= OI01IO11;
|
||||
O1111O0O <= OOlIO1OO;
|
||||
lll0OO11 <= I0I0O1l1;
|
||||
end else begin
|
||||
I01O0111 <= -1;
|
||||
l10Ol00O <= 1'bX;
|
||||
O1111O0O <= 1'bX;
|
||||
lll0OO11 <= 1'bX;
|
||||
end
|
||||
end else begin
|
||||
I01O0111 <= -1;
|
||||
l10Ol00O <= 1'bX;
|
||||
O1111O0O <= 1'bX;
|
||||
lll0OO11 <= 1'bX;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_d or negedge rst_d_n) begin : a1003_PROC
|
||||
if (rst_d_n === 1'b0) begin
|
||||
OlOOO000 <= 1'b0;
|
||||
OO001I10 <= 1'b0;
|
||||
OOOOIlO1 <= 0;
|
||||
O100OIlI <= 1'b0;
|
||||
IIOOI0Ol <= 1'b0;
|
||||
l011lO0l <= 1'b0;
|
||||
Il1O110I <= 1'b0;
|
||||
O1OOO1O0 <= 1'b0;
|
||||
IO00llI0 <= 1'b0;
|
||||
end else if (rst_d_n === 1'b1) begin
|
||||
if (init_d_n === 1'b0) begin
|
||||
OlOOO000 <= 1'b0;
|
||||
OO001I10 <= 1'b0;
|
||||
OOOOIlO1 <= 0;
|
||||
O100OIlI <= 1'b0;
|
||||
IIOOI0Ol <= 1'b0;
|
||||
l011lO0l <= 1'b0;
|
||||
Il1O110I <= 1'b0;
|
||||
O1OOO1O0 <= 1'b0;
|
||||
IO00llI0 <= 1'b0;
|
||||
end else if (init_d_n === 1'b1) begin
|
||||
OlOOO000 <= IOIOOIlO;
|
||||
OO001I10 <= lI1IO1O0;
|
||||
OOOOIlO1 <= OI1IO11l;
|
||||
O100OIlI <= l0IlI00O;
|
||||
IIOOI0Ol <= O100OIlI;
|
||||
l011lO0l <= l00O0lO1;
|
||||
Il1O110I <= l0Ol100I;
|
||||
O1OOO1O0 <= O0OIl111;
|
||||
IO00llI0 <= O0III10l;
|
||||
end else begin
|
||||
OlOOO000 <= 1'bX;
|
||||
OO001I10 <= 1'bX;
|
||||
OOOOIlO1 <= -1;
|
||||
O100OIlI <= 1'bX;
|
||||
IIOOI0Ol <= 1'bX;
|
||||
l011lO0l <= 1'bX;
|
||||
Il1O110I <= 1'bX;
|
||||
O1OOO1O0 <= 1'bX;
|
||||
IO00llI0 <= 1'bX;
|
||||
end
|
||||
end else begin
|
||||
OlOOO000 <= 1'bX;
|
||||
OO001I10 <= 1'bX;
|
||||
OOOOIlO1 <= -1;
|
||||
O100OIlI <= 1'bX;
|
||||
IIOOI0Ol <= 1'bX;
|
||||
l011lO0l <= 1'bX;
|
||||
Il1O110I <= 1'bX;
|
||||
O1OOO1O0 <= 1'bX;
|
||||
IO00llI0 <= 1'bX;
|
||||
end
|
||||
end
|
||||
|
||||
assign clr_sync_s = OI01IO11;
|
||||
assign clr_cmplt_s = lll0OO11;
|
||||
assign clr_in_prog_s = (reg_in_prog == 0) ? OOlIO1OO : O1111O0O;
|
||||
assign clr_in_prog_d = (reg_in_prog == 0) ? O100OIlI : IIOOI0Ol;
|
||||
assign clr_sync_d = Il1O110I;
|
||||
assign clr_cmplt_d = O1OOO1O0;
|
||||
|
||||
|
||||
|
||||
always @ (clk_s) begin : monitor_clk_s
|
||||
if ( (clk_s !== 1'b0) && (clk_s !== 1'b1) && ($time > 0) )
|
||||
$display( "WARNING: %m :\n at time = %t, detected unknown value, %b, on clk_s input.",
|
||||
$time, clk_s );
|
||||
end // monitor_clk_s
|
||||
|
||||
always @ (clk_d) begin : monitor_clk_d
|
||||
if ( (clk_d !== 1'b0) && (clk_d !== 1'b1) && ($time > 0) )
|
||||
$display( "WARNING: %m :\n at time = %t, detected unknown value, %b, on clk_d input.",
|
||||
$time, clk_d );
|
||||
end // monitor_clk_d
|
||||
|
||||
|
||||
// synopsys translate_on
|
||||
`undef DW_IIOOl10O
|
||||
endmodule
|
||||
/* vcs gen_ip dbg_ip off */
|
||||
/* */
|
||||
|
|
@ -0,0 +1,496 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This confidential and proprietary software may be used only
|
||||
// as authorized by a licensing agreement from Synopsys Inc.
|
||||
// In the event of publication, the following notice is applicable:
|
||||
//
|
||||
// (C) COPYRIGHT 2005 - 2018 SYNOPSYS INC.
|
||||
// ALL RIGHTS RESERVED
|
||||
//
|
||||
// The entire notice above must be reproduced on all authorized
|
||||
// copies.
|
||||
//
|
||||
// AUTHOR: Doug Lee 12/20/05
|
||||
//
|
||||
// VERSION: Simulation Architecture
|
||||
//
|
||||
// DesignWare_version: 2105953f
|
||||
// DesignWare_release: O-2018.06-DWBB_201806.1
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ABSTRACT: Data Stream Synchronizer Simulation Model
|
||||
//
|
||||
// This synchronizes an incoming data stream from a source domain
|
||||
// to a destination domain with a minimum amount of latency.
|
||||
//
|
||||
// Parameters: Valid Values Description
|
||||
// ========== ============ ===========
|
||||
// width 1 to 1024 default: 8
|
||||
// Width of data_s and data_d ports
|
||||
//
|
||||
// depth 2 to 256 default: 4
|
||||
// Depth of FIFO
|
||||
//
|
||||
// prefill_lvl 0 to depth-1 default: 0
|
||||
// number of FIFO locations filled before
|
||||
// transferring to destination domain ]
|
||||
//
|
||||
// f_sync_type 0 to 4 default: 2
|
||||
// Forward Synchronization Type (Source to Destination Domains)
|
||||
// 0 => no synchronization, single clock system
|
||||
// 1 => 2-stage synchronization w/ 1st stage neg-edge & 2nd stage pos-edge capturing
|
||||
// 2 => 2-stage synchronization w/ both stages pos-edge capturing
|
||||
// 3 => 3-stage synchronization w/ all stages pos-edge capturing
|
||||
// 4 => 4-stage synchronization w/ all stages pos-edge capturing
|
||||
//
|
||||
// reg_stat 0 or 1 default: 1
|
||||
// Register internally calculated status
|
||||
// 0 => don't register internally calculated status
|
||||
// 1 => register internally calculated status
|
||||
//
|
||||
// tst_mode 0 or 2 default: 0
|
||||
// Insert neg-edge hold latch at front-end of synchronizers during "test"
|
||||
// 0 => no hold latch inserted,
|
||||
// 1 => insert hold 'latch' using a neg-edge triggered register
|
||||
// 2 => insert hold latch using an active low latch
|
||||
//
|
||||
// verif_en 0 to 4 default: 1
|
||||
// Enable missampling of synchronized signals during simulation
|
||||
// 0 => no sampling errors inserted,
|
||||
// 1 => sampling errors are randomly inserted with 0 or up to 1 destination clock cycle delays
|
||||
// 2 => sampling errors are randomly inserted with 0, 0.5, 1, or 1.5 destination clock cycle delays
|
||||
// 3 => sampling errors are randomly inserted with 0, 1, 2, or 3 destination clock cycle delays
|
||||
// 4 => sampling errors are randomly inserted with 0 or up to 0.5 destination clock cycle delays
|
||||
//
|
||||
// r_sync_type 0 to 4 default: 2
|
||||
// Reverse Synchronization Type (Destination to Source Domains)
|
||||
// 0 => no synchronization, single clock system
|
||||
// 1 => 2-stage synchronization w/ 1st stage neg-edge & 2nd stage pos-edge capturing
|
||||
// 2 => 2-stage synchronization w/ both stages pos-edge capturing
|
||||
// 3 => 3-stage synchronization w/ all stages pos-edge capturing
|
||||
// 4 => 4-stage synchronization w/ all stages pos-edge capturing
|
||||
//
|
||||
// clk_d_faster 0 to 15 default: 1
|
||||
// clk_d faster than clk_s by difference ratio
|
||||
// 0 => Either clr_s or clr_d active with the other tied low at input
|
||||
// 1 to 15 => ratio of clk_d to clk_s frequencies plus 1
|
||||
//
|
||||
// reg_in_prog 0 or 1 default: 1
|
||||
// Register the 'clr_in_prog_s' and 'clr_in_prog_d' Outputs
|
||||
// 0 => unregistered
|
||||
// 1 => registered
|
||||
//
|
||||
// Input Ports: Size Description
|
||||
// =========== ==== ===========
|
||||
// clk_s 1 bit Source Domain Input Clock
|
||||
// rst_s_n 1 bit Source Domain Active Low Async. Reset
|
||||
// init_s_n 1 bit Source Domain Active Low Sync. Reset
|
||||
// clr_s 1 bit Source Domain Internal Logic Clear (reset)
|
||||
// send_s 1 bit Source Domain Active High Send Request
|
||||
// data_s N bits Source Domain Data
|
||||
//
|
||||
// clk_d 1 bit Destination Domain Input Clock
|
||||
// rst_d_n 1 bit Destination Domain Active Low Async. Reset
|
||||
// init_d_n 1 bit Destination Domain Active Low Sync. Reset
|
||||
// clr_d 1 bit Destination Domain Internal Logic Clear (reset)
|
||||
// prefill_d 1 bit Destination Domain Prefill Control
|
||||
//
|
||||
// test 1 bit Test input
|
||||
//
|
||||
// Output Ports Size Description
|
||||
// ============ ==== ===========
|
||||
// clr_sync_d 1 bit Source Domain Clear
|
||||
// clr_in_prog_s 1 bit Source Domain Clear in Progress
|
||||
// clr_cmplt_s 1 bit Soruce Domain Clear Complete (pulse)
|
||||
//
|
||||
// clr_in_prog_d 1 bit Destination Domain Clear in Progress
|
||||
// clr_sync_d 1 bit Destination Domain Clear (pulse)
|
||||
// clr_cmplt_d 1 bit Destination Domain Clear Complete (pulse)
|
||||
// data_avail_d 1 bit Destination Domain Data Available
|
||||
// data_d N bits Destination Domain Data
|
||||
// prefilling_d 1 bit Destination Domain Prefillng Status
|
||||
//
|
||||
// Note: (1) The value of N is equal to the 'width' parameter value
|
||||
//
|
||||
//
|
||||
// MODIFIED:
|
||||
// 05/06/16 RJK Removed some X propagation coding that interferes with VCS
|
||||
// NLP flow and is redundant since VCS added X propagation options
|
||||
//
|
||||
// 07/25/11 DLL Removed or-ing of 'clr_in_prog_d' with 'init_d_n' that
|
||||
// wires to DW_sync 'init_d_n' input port.
|
||||
// Added checking and comments for tst_mode = 2.
|
||||
//
|
||||
// 10/20/06 DLL Updated with new version of DW_reset_sync
|
||||
//
|
||||
// 11/15/06 DLL Added 4-stage synchronization capability
|
||||
//
|
||||
// 7/13/09 DLL Changed all `define declarations to have the
|
||||
// "DW_" prefix and then `undef them at the approprite time.
|
||||
//
|
||||
//
|
||||
//
|
||||
module DW_stream_sync (
|
||||
clk_s,
|
||||
rst_s_n,
|
||||
init_s_n,
|
||||
clr_s,
|
||||
send_s,
|
||||
data_s,
|
||||
clr_sync_s,
|
||||
clr_in_prog_s,
|
||||
clr_cmplt_s,
|
||||
|
||||
clk_d,
|
||||
rst_d_n,
|
||||
init_d_n,
|
||||
clr_d,
|
||||
prefill_d,
|
||||
clr_in_prog_d,
|
||||
clr_sync_d,
|
||||
clr_cmplt_d,
|
||||
data_avail_d,
|
||||
data_d,
|
||||
prefilling_d,
|
||||
|
||||
test
|
||||
);
|
||||
|
||||
parameter integer width = 8; // RANGE 1 to 1024
|
||||
parameter integer depth = 4; // RANGE 2 to 256
|
||||
parameter integer prefill_lvl = 0; // RANGE 0 to 255
|
||||
parameter integer f_sync_type = 2; // RANGE 0 to 4
|
||||
parameter integer reg_stat = 1; // RANGE 0 to 1
|
||||
parameter integer tst_mode = 0; // RANGE 0 to 2
|
||||
parameter integer verif_en = 1; // RANGE 0 to 4
|
||||
parameter integer r_sync_type = 2; // RANGE 0 to 4
|
||||
parameter integer clk_d_faster = 1; // RANGE 0 to 15
|
||||
parameter integer reg_in_prog = 1; // RANGE 0 to 1
|
||||
|
||||
localparam cnt_depth = ((depth>16)?((depth>64)?((depth>128)?8:7):((depth>32)?6:5)):((depth>4)?((depth>8)?4:3):((depth>2)?2:1)));
|
||||
localparam sync_verif_en = (verif_en == 2) ? 4 : (verif_en == 3) ? 1 : verif_en;
|
||||
|
||||
|
||||
input clk_s; // clock input from source domain
|
||||
input rst_s_n; // active low asynchronous reset from source domain
|
||||
input init_s_n; // active low synchronous reset from source domain
|
||||
input clr_s; // active high clear from source domain
|
||||
input send_s; // active high send request from source domain
|
||||
input [width-1:0] data_s; // data to be synchronized from source domain
|
||||
output clr_sync_s; // clear to source domain sequential devices
|
||||
output clr_in_prog_s; // clear in progress status to source domain
|
||||
output clr_cmplt_s; // clear sequence complete (pulse)
|
||||
|
||||
input clk_d; // clock input from destination domain
|
||||
input rst_d_n; // active low asynchronous reset from destination domain
|
||||
input init_d_n; // active low synchronous reset from destination domain
|
||||
input clr_d; // active high clear from destination domain
|
||||
input prefill_d; // active high prefill control from destination domain
|
||||
output clr_in_prog_d; // clear in progress status to source domain
|
||||
output clr_sync_d; // clear to destination domain sequential devices (pulse)
|
||||
output clr_cmplt_d; // clear sequence complete (pulse)
|
||||
output data_avail_d; // data available to destination domain
|
||||
output [width-1:0] data_d; // data synchronized to destination domain
|
||||
output prefilling_d; // prefilling status to destination domain
|
||||
|
||||
input test; // test input
|
||||
|
||||
// synopsys translate_off
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Parameter legality check
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
|
||||
initial begin : parameter_check
|
||||
integer param_err_flg;
|
||||
|
||||
param_err_flg = 0;
|
||||
|
||||
|
||||
if ( (depth < 2) || (depth > 256) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter depth (legal range: 2 to 256)",
|
||||
depth );
|
||||
end
|
||||
|
||||
if ( (prefill_lvl < 0) || (prefill_lvl > depth-1) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter prefill_lvl (legal range: 0 to depth-1)",
|
||||
prefill_lvl );
|
||||
end
|
||||
|
||||
if ( ((f_sync_type & 7) < 0) || ((f_sync_type & 7) > 4) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter (f_sync_type & 7) (legal range: 0 to 4)",
|
||||
(f_sync_type & 7) );
|
||||
end
|
||||
|
||||
if ( (reg_stat < 0) || (reg_stat > 1) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter reg_stat (legal range: 0 to 1)",
|
||||
reg_stat );
|
||||
end
|
||||
|
||||
if ( (tst_mode < 0) || (tst_mode > 2) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter tst_mode (legal range: 0 to 2)",
|
||||
tst_mode );
|
||||
end
|
||||
|
||||
if ( (verif_en < 0) || (verif_en > 4) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter verif_en (legal range: 0 to 4)",
|
||||
verif_en );
|
||||
end
|
||||
|
||||
if ( ((r_sync_type & 7) < 0) || ((r_sync_type & 7) > 4) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter (r_sync_type & 7) (legal range: 0 to 4)",
|
||||
(r_sync_type & 7) );
|
||||
end
|
||||
|
||||
if ( (clk_d_faster < 0) || (clk_d_faster > 15) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter clk_d_faster (legal range: 0 to 15)",
|
||||
clk_d_faster );
|
||||
end
|
||||
|
||||
if ( (reg_in_prog < 0) || (reg_in_prog > 1) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter reg_in_prog (legal range: 0 to 1)",
|
||||
reg_in_prog );
|
||||
end
|
||||
|
||||
if ( param_err_flg == 1) begin
|
||||
$display(
|
||||
"%m :\n Simulation aborted due to invalid parameter value(s)");
|
||||
$finish;
|
||||
end
|
||||
|
||||
end // parameter_check
|
||||
|
||||
|
||||
wire next_data_avail_d_int;
|
||||
reg data_avail_d_int;
|
||||
wire [width-1:0] next_data_d_int;
|
||||
reg [width-1:0] data_d_int;
|
||||
wire next_prefilling_d_int;
|
||||
reg prefilling_d_int;
|
||||
|
||||
reg [width-1:0] data_mem [0:depth-1];
|
||||
|
||||
wire [cnt_depth-1:0] next_wr_ptr_s;
|
||||
reg [cnt_depth-1:0] wr_ptr_s;
|
||||
wire [cnt_depth-1:0] next_rd_ptr_d;
|
||||
reg [cnt_depth-1:0] rd_ptr_d;
|
||||
|
||||
reg [cnt_depth-1:0] next_valid_cnt;
|
||||
reg [cnt_depth-1:0] valid_cnt;
|
||||
|
||||
wire [depth-1:0] next_event_vec_s;
|
||||
reg [depth-1:0] event_vec_s;
|
||||
reg [depth-1:0] event_vec_l;
|
||||
wire [depth-1:0] event_vec_selected;
|
||||
wire [depth-1:0] dw_sync_event_vec;
|
||||
|
||||
wire next_detect_lvl;
|
||||
reg detect_lvl;
|
||||
|
||||
wire [31:0] one;
|
||||
|
||||
integer i, idx;
|
||||
|
||||
assign one = 1;
|
||||
|
||||
|
||||
initial begin
|
||||
if ((f_sync_type > 0)&&(f_sync_type < 8))
|
||||
$display("Information: *** Instance %m is the DW_stream_sync Clock Domain Crossing Module ***");
|
||||
end
|
||||
|
||||
|
||||
|
||||
DW_reset_sync #((f_sync_type + 8), (r_sync_type + 8), clk_d_faster, reg_in_prog, tst_mode, verif_en) U_RST_SYNC (
|
||||
.clk_s(clk_s),
|
||||
.rst_s_n(rst_s_n),
|
||||
.init_s_n(init_s_n),
|
||||
.clr_s(clr_s),
|
||||
.clk_d(clk_d),
|
||||
.rst_d_n(rst_d_n),
|
||||
.init_d_n(init_d_n),
|
||||
.clr_d(clr_d),
|
||||
.test(test),
|
||||
.clr_sync_s(clr_sync_s),
|
||||
.clr_in_prog_s(clr_in_prog_s),
|
||||
.clr_cmplt_s(clr_cmplt_s),
|
||||
.clr_in_prog_d(clr_in_prog_d),
|
||||
.clr_sync_d(clr_sync_d),
|
||||
.clr_cmplt_d(clr_cmplt_d)
|
||||
);
|
||||
|
||||
|
||||
|
||||
always @(posedge clk_s or negedge rst_s_n) begin : a1001_PROC
|
||||
if (rst_s_n == 1'b0) begin
|
||||
for (idx = 0; idx < depth; idx = idx + 1) begin
|
||||
data_mem[idx] <= {width{1'b0}};
|
||||
end
|
||||
end else begin
|
||||
if (!init_s_n || clr_in_prog_s) begin
|
||||
for (idx = 0; idx < depth; idx = idx + 1) begin
|
||||
data_mem[idx] <= {width{1'b0}};
|
||||
end
|
||||
end else begin
|
||||
if (send_s == 1'b1) begin
|
||||
data_mem[wr_ptr_s] <= data_s;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
assign next_wr_ptr_s = (send_s == 1'b1) ? ((wr_ptr_s === depth-1) ? {cnt_depth{1'b0}} :
|
||||
wr_ptr_s + one[cnt_depth-1:0]) : wr_ptr_s;
|
||||
|
||||
assign next_event_vec_s = (send_s == 1'b1) ? {event_vec_s[depth-2:0], ~event_vec_s[depth-1]} :
|
||||
event_vec_s;
|
||||
|
||||
|
||||
|
||||
generate
|
||||
if (((f_sync_type&7)>1)&&(tst_mode==2)) begin : GEN_LATCH_hold_latch_PROC
|
||||
reg [depth-1:0] event_vec_l;
|
||||
always @ (clk_s or event_vec_s) begin : LATCH_hold_latch_PROC_PROC
|
||||
|
||||
if (clk_s == 1'b0)
|
||||
|
||||
event_vec_l = event_vec_s;
|
||||
|
||||
|
||||
end // LATCH_hold_latch_PROC_PROC
|
||||
|
||||
|
||||
assign event_vec_selected = (test==1'b1)? event_vec_l : event_vec_s;
|
||||
|
||||
end else begin : GEN_DIRECT_hold_latch_PROC
|
||||
assign event_vec_selected = event_vec_s;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
DW_sync #(depth, f_sync_type+8, tst_mode, sync_verif_en) U_SYNC(
|
||||
.clk_d(clk_d),
|
||||
.rst_d_n(rst_d_n),
|
||||
.init_d_n(init_d_n),
|
||||
.data_s(event_vec_selected),
|
||||
.test(test),
|
||||
.data_d(dw_sync_event_vec) );
|
||||
|
||||
always @(dw_sync_event_vec or next_valid_cnt or rd_ptr_d) begin : a1002_PROC
|
||||
next_valid_cnt = {cnt_depth{1'b0}};
|
||||
for (i = 0; i < depth; i = i + 1) begin
|
||||
if (rd_ptr_d > i) begin
|
||||
next_valid_cnt = next_valid_cnt + (dw_sync_event_vec[i] === ~detect_lvl);
|
||||
end else begin
|
||||
next_valid_cnt = next_valid_cnt + (dw_sync_event_vec[i] === detect_lvl);
|
||||
end
|
||||
if (dw_sync_event_vec[i] === 1'bX)
|
||||
next_valid_cnt = {cnt_depth{1'b0}};
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
assign next_rd_ptr_d = next_data_avail_d_int ? ((rd_ptr_d === depth-1) ? {cnt_depth{1'b0}} : (rd_ptr_d + one[cnt_depth-1:0])) :
|
||||
rd_ptr_d;
|
||||
|
||||
assign next_detect_lvl = (next_data_avail_d_int && (next_rd_ptr_d === {cnt_depth{1'b0}})) ?
|
||||
~detect_lvl : detect_lvl;
|
||||
|
||||
|
||||
assign next_prefilling_d_int = ((prefill_d === 1'bX) || (prefilling_d_int === 1'bX)) ? 1'bX :
|
||||
(prefill_lvl == 0) ? 1'b0 :
|
||||
((prefill_d === 1'b1) && (prefill_lvl > (reg_stat ? valid_cnt : next_valid_cnt))) ? 1'b1 :
|
||||
(prefill_lvl <= (reg_stat ? valid_cnt : next_valid_cnt)) ? 1'b0 : prefilling_d_int;
|
||||
|
||||
assign next_data_avail_d_int = ((dw_sync_event_vec[rd_ptr_d] === 1'bX) || (next_prefilling_d_int === 1'bX)) ? 1'bX :
|
||||
(next_prefilling_d_int === 1'b0) && (detect_lvl === dw_sync_event_vec[rd_ptr_d]) ? 1'b1 : 1'b0;
|
||||
|
||||
assign next_data_d_int = (next_data_avail_d_int === 1'bX) ? {width{1'bX}} :
|
||||
(next_data_avail_d_int === 1'b1) ? data_mem[rd_ptr_d] : data_d_int;
|
||||
|
||||
|
||||
always @(posedge clk_s or negedge rst_s_n) begin : a1003_PROC
|
||||
if (rst_s_n == 1'b0) begin
|
||||
wr_ptr_s <= {cnt_depth{1'b0}};
|
||||
event_vec_s <= {depth{1'b0}};
|
||||
end else begin
|
||||
if ((init_s_n == 1'b0) || (clr_in_prog_s == 1'b1)) begin
|
||||
wr_ptr_s <= {cnt_depth{1'b0}};
|
||||
event_vec_s <= {depth{1'b0}};
|
||||
end else begin
|
||||
wr_ptr_s <= next_wr_ptr_s;
|
||||
event_vec_s <= next_event_vec_s;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_d or negedge rst_d_n) begin : a1004_PROC
|
||||
if (rst_d_n == 1'b0) begin
|
||||
rd_ptr_d <= {cnt_depth{1'b0}};
|
||||
valid_cnt <= {cnt_depth{1'b0}};
|
||||
detect_lvl <= 1'b1;
|
||||
data_avail_d_int <= 1'b0;
|
||||
data_d_int <= {width{1'b0}};
|
||||
prefilling_d_int <= 1'b0;
|
||||
end else begin
|
||||
if ((init_d_n == 1'b0) || (clr_in_prog_d == 1'b1)) begin
|
||||
rd_ptr_d <= {cnt_depth{1'b0}};
|
||||
valid_cnt <= {cnt_depth{1'b0}};
|
||||
detect_lvl <= 1'b1;
|
||||
data_avail_d_int <= 1'b0;
|
||||
data_d_int <= {width{1'b0}};
|
||||
prefilling_d_int <= 1'b0;
|
||||
end else begin
|
||||
rd_ptr_d <= next_rd_ptr_d;
|
||||
valid_cnt <= next_valid_cnt;
|
||||
detect_lvl <= next_detect_lvl;
|
||||
data_avail_d_int <= next_data_avail_d_int;
|
||||
data_d_int <= next_data_d_int;
|
||||
prefilling_d_int <= next_prefilling_d_int;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign data_avail_d = data_avail_d_int;
|
||||
assign data_d = data_d_int;
|
||||
assign prefilling_d = prefilling_d_int;
|
||||
|
||||
|
||||
|
||||
always @ (clk_s) begin : monitor_clk_s
|
||||
if ( (clk_s !== 1'b0) && (clk_s !== 1'b1) && ($time > 0) )
|
||||
$display( "WARNING: %m :\n at time = %t, detected unknown value, %b, on clk_s input.",
|
||||
$time, clk_s );
|
||||
end // monitor_clk_s
|
||||
|
||||
always @ (clk_d) begin : monitor_clk_d
|
||||
if ( (clk_d !== 1'b0) && (clk_d !== 1'b1) && ($time > 0) )
|
||||
$display( "WARNING: %m :\n at time = %t, detected unknown value, %b, on clk_d input.",
|
||||
$time, clk_d );
|
||||
end // monitor_clk_d
|
||||
|
||||
// synopsys translate_on
|
||||
endmodule
|
||||
/* vcs gen_ip dbg_ip off */
|
||||
/* */
|
||||
|
|
@ -0,0 +1,385 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This confidential and proprietary software may be used only
|
||||
// as authorized by a licensing agreement from Synopsys Inc.
|
||||
// In the event of publication, the following notice is applicable:
|
||||
//
|
||||
// (C) COPYRIGHT 2005 - 2018 SYNOPSYS INC.
|
||||
// ALL RIGHTS RESERVED
|
||||
//
|
||||
// The entire notice above must be reproduced on all authorized
|
||||
// copies.
|
||||
//
|
||||
// AUTHOR: Doug Lee 3/3/05
|
||||
//
|
||||
// VERSION: Simulation Architecture
|
||||
//
|
||||
// DesignWare_version: c5e9837c
|
||||
// DesignWare_release: O-2018.06-DWBB_201806.1
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ABSTRACT: Fundamental Synchronizer Simulation Model
|
||||
//
|
||||
// This synchronizes incoming data into the destination domain
|
||||
// with a configurable number of sampling stages.
|
||||
//
|
||||
// Parameters: Valid Values
|
||||
// ========== ============
|
||||
// width [ 1 to 1024 ]
|
||||
// f_sync_type [ 0 = single clock design, no synchronizing stages implemented,
|
||||
// 1 = 2-stage synchronization w/ 1st stage neg-edge & 2nd stage pos-edge capturing,
|
||||
// 2 = 2-stage synchronization w/ both stages pos-edge capturing,
|
||||
// 3 = 3-stage synchronization w/ all stages pos-edge capturing,
|
||||
// 4 = 4-stage synchronization w/ all stages pos-edge capturing ]
|
||||
// tst_mode [ 0 = no hold latch inserted,
|
||||
// 1 = insert hold 'latch' using a neg-edge triggered register
|
||||
// 2 = reserved (functions same as tst_mode=0 ]
|
||||
// verif_en [ 0 = no sampling errors inserted,
|
||||
// 1 = sampling errors are randomly inserted with 0 or 1 destination clock cycle delays
|
||||
// 2 = sampling errors are randomly inserted with 0, 0.5, 1, or 1.5 destination clock cycle delays
|
||||
// 3 = sampling errors are randomly inserted with 0, 1, 2, or 3 destination clock cycle delays
|
||||
// 4 = sampling errors are randomly inserted with 0 or up to 0.5 destination clock cycle delays ]
|
||||
//
|
||||
// Input Ports: Size Description
|
||||
// =========== ==== ===========
|
||||
// clk_d 1 bit Destination Domain Input Clock
|
||||
// rst_d_n 1 bit Destination Domain Active Low Async. Reset
|
||||
// init_d_n 1 bit Destination Domain Active Low Sync. Reset
|
||||
// data_s N bits Source Domain Data Input
|
||||
// test 1 bit Test input
|
||||
//
|
||||
// Output Ports Size Description
|
||||
// ============ ==== ===========
|
||||
// data_d N bits Destination Domain Data Output
|
||||
//
|
||||
// Note: the value of N is equal to the 'width' parameter value
|
||||
//
|
||||
//
|
||||
// MODIFIED:
|
||||
// RJK 09-17-13 updated to eliminate race (STAR 9000661688)
|
||||
// RJK 01-15-13 updated to eliminate `define
|
||||
// RJK 10-11-12 corrected test mode behavior when tst_mode=2
|
||||
// DLL 8-8-11 Added tst_mode=2 (not a functional change)
|
||||
// DLL 6-12-06 Removed unnecessary To_X01 processing of 'data_s_int'
|
||||
//
|
||||
// DLL 11-7-06 Modified functionality to support f_sync_type = 4
|
||||
//
|
||||
// DLL 11-14-06 Revised approach to routing missampling of data_s
|
||||
//
|
||||
//
|
||||
// DLL 8-18-10 Fixed typo that results in correct resolution of 'data_s_delta_t'
|
||||
// in the missampling code. Addresses STAR#9000412693.
|
||||
|
||||
module DW_sync (
|
||||
clk_d,
|
||||
rst_d_n,
|
||||
init_d_n,
|
||||
data_s,
|
||||
test,
|
||||
data_d
|
||||
);
|
||||
|
||||
parameter integer width = 8;
|
||||
parameter integer f_sync_type = 2;
|
||||
parameter integer tst_mode = 0;
|
||||
parameter integer verif_en = 1;
|
||||
|
||||
input clk_d;
|
||||
input rst_d_n;
|
||||
input init_d_n;
|
||||
input [width-1:0] data_s;
|
||||
input test;
|
||||
output [width-1:0] data_d;
|
||||
|
||||
// synopsys translate_off
|
||||
localparam F_SYNC_TYPE_INT = f_sync_type % 8;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Parameter legality check
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
|
||||
initial begin : parameter_check
|
||||
integer param_err_flg;
|
||||
|
||||
param_err_flg = 0;
|
||||
|
||||
|
||||
if (width < 1 ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter width (lower bound: 1 )",
|
||||
width );
|
||||
end
|
||||
|
||||
if ( (F_SYNC_TYPE_INT < 0) || (F_SYNC_TYPE_INT > 4) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter F_SYNC_TYPE_INT (legal range: 0 to 4)",
|
||||
F_SYNC_TYPE_INT );
|
||||
end
|
||||
|
||||
if ( (verif_en < 0) || (verif_en > 4) ) begin
|
||||
param_err_flg = 1;
|
||||
$display(
|
||||
"ERROR: %m :\n Invalid value (%d) for parameter verif_en (legal range: 0 to 4)",
|
||||
verif_en );
|
||||
end
|
||||
|
||||
if ( param_err_flg == 1) begin
|
||||
$display(
|
||||
"%m :\n Simulation aborted due to invalid parameter value(s)");
|
||||
$finish;
|
||||
end
|
||||
|
||||
end // parameter_check
|
||||
|
||||
|
||||
wire [width-1:0] data_s_int;
|
||||
reg [width-1:0] ndata1_int;
|
||||
reg [width-1:0] data1_int;
|
||||
reg [width-1:0] data_d2_int;
|
||||
reg [width-1:0] data_d3_int;
|
||||
reg [width-1:0] data_d4_int;
|
||||
reg [width-1:0] test_nout1_int;
|
||||
|
||||
wire [width-1:0] next_data1_int;
|
||||
wire [width-1:0] next_data_d2_int;
|
||||
wire [width-1:0] next_data_d3_int;
|
||||
wire [width-1:0] tst_mode_sel_data;
|
||||
wire [width-1:0] f_sync_type0_data;
|
||||
|
||||
|
||||
`ifdef DW_MODEL_MISSAMPLES
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
initial begin
|
||||
$display("Information: %m: *** Running with DW_MODEL_MISSAMPLES defined, verif_en is: %0d ***",
|
||||
verif_en);
|
||||
end
|
||||
|
||||
reg [width-1:0] test_hold_ms;
|
||||
wire hclk_odd;
|
||||
reg [width-1:0] last_data_dyn, data_s_delta_t;
|
||||
reg [width-1:0] last_data_s, last_data_s_q, last_data_s_qq;
|
||||
wire [width-1:0] data_s_sel_0, data_s_sel_1;
|
||||
reg [width-1:0] data_select; initial data_select = 0;
|
||||
reg [width-1:0] data_select_2; initial data_select_2 = 0;
|
||||
|
||||
always @ (negedge clk_d or negedge rst_d_n) begin : PROC_test_hold_ms_registers
|
||||
if (rst_d_n == 1'b0) begin
|
||||
test_hold_ms <= {width{1'b0}};
|
||||
end else if (init_d_n == 1'b0) begin
|
||||
test_hold_ms <= {width{1'b0}};
|
||||
end else begin
|
||||
test_hold_ms <= data_s;
|
||||
end
|
||||
end
|
||||
reg init_dly_n;
|
||||
|
||||
|
||||
always @ (posedge hclk_odd or data_s or rst_d_n) begin : PROC_catch_last_data
|
||||
data_s_delta_t <= (data_s | (data_s ^ data_s)) & {width{rst_d_n}} & {width{init_dly_n}};
|
||||
last_data_dyn <= data_s_delta_t & {width{rst_d_n}} & {width{init_dly_n}};
|
||||
end // PROC_catch_last_data
|
||||
|
||||
generate if ((verif_en % 2) == 1) begin : GEN_HO_VE_EVEN
|
||||
assign hclk_odd = clk_d;
|
||||
end else begin : GEN_HO_VE_ODD
|
||||
assign hclk_odd = ~clk_d;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @ (posedge clk_d or negedge rst_d_n) begin : PROC_missample_hist_even
|
||||
if (rst_d_n == 1'b0) begin
|
||||
last_data_s_q <= {width{1'b0}};
|
||||
init_dly_n <= 1'b1;
|
||||
end else if (init_d_n == 1'b0) begin
|
||||
last_data_s_q <= {width{1'b0}};
|
||||
init_dly_n <= 1'b0;
|
||||
end else begin
|
||||
last_data_s_q <= last_data_s;
|
||||
init_dly_n <= 1'b1;
|
||||
end
|
||||
end // PROC_missample_hist_even
|
||||
|
||||
always @ (posedge hclk_odd or negedge rst_d_n) begin : PROC_missample_hist_odd
|
||||
if (rst_d_n == 1'b0) begin
|
||||
last_data_s <= {width{1'b0}};
|
||||
last_data_s_qq <= {width{1'b0}};
|
||||
end else if (init_d_n == 1'b0) begin
|
||||
last_data_s <= {width{1'b0}};
|
||||
last_data_s_qq <= {width{1'b0}};
|
||||
end else begin
|
||||
last_data_s <= (data_s | (data_s ^ data_s));
|
||||
last_data_s_qq <= last_data_s_q;
|
||||
end
|
||||
end // PROC_missample_hist_odd
|
||||
|
||||
always @ (data_s or last_data_s) begin : PROC_mk_next_data_select
|
||||
if (data_s != last_data_s) begin
|
||||
data_select = wide_random(width);
|
||||
|
||||
if ((verif_en == 2) || (verif_en == 3))
|
||||
data_select_2 = wide_random(width);
|
||||
else
|
||||
data_select_2 = {width{1'b0}};
|
||||
end
|
||||
end // PROC_mk_next_data_select
|
||||
|
||||
assign data_s_sel_0 = (verif_en < 1)? data_s : ((data_s & ~data_select) | (last_data_dyn & data_select));
|
||||
|
||||
assign data_s_sel_1 = (verif_en < 2)? {width{1'b0}} : ((last_data_s_q & ~data_select) | (last_data_s_qq & data_select));
|
||||
|
||||
assign data_s_int = ((data_s_sel_0 & ~data_select_2) | (data_s_sel_1 & data_select_2));
|
||||
|
||||
|
||||
function [width-1:0] wide_random;
|
||||
input [31:0] in_width; // should match "width" parameter -- need one input to satisfy Verilog function requirement
|
||||
|
||||
reg [width-1:0] temp_result;
|
||||
reg [31:0] rand_slice;
|
||||
integer i, j, base;
|
||||
|
||||
|
||||
begin
|
||||
temp_result = $random;
|
||||
if (((width / 32) + 1) > 1) begin
|
||||
for (i=1 ; i < ((width / 32) + 1) ; i=i+1) begin
|
||||
base = i << 5;
|
||||
rand_slice = $random;
|
||||
for (j=0 ; ((j < 32) && (base+j < in_width)) ; j=j+1) begin
|
||||
temp_result[base+j] = rand_slice[j];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wide_random = temp_result;
|
||||
end
|
||||
endfunction // wide_random
|
||||
|
||||
initial begin : seed_random_PROC
|
||||
integer seed, init_rand;
|
||||
`ifdef DW_MISSAMPLE_SEED
|
||||
seed = `DW_MISSAMPLE_SEED;
|
||||
`else
|
||||
seed = 32'h0badbeef;
|
||||
`endif
|
||||
|
||||
init_rand = $random(seed);
|
||||
end // seed_random_PROC
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
`else
|
||||
assign data_s_int = (data_s | (data_s ^ data_s));
|
||||
`endif
|
||||
|
||||
|
||||
initial begin
|
||||
if ((f_sync_type > 0)&&(f_sync_type < 8))
|
||||
$display("Information: *** Instance %m is the DW_sync Clock Domain Crossing Module ***");
|
||||
end
|
||||
|
||||
`ifdef DW_REPORT_SYNC_PARAMS
|
||||
initial begin
|
||||
if (F_SYNC_TYPE_INT > 0)
|
||||
$display("Information: *** Instance %m is configured as follows: width is: %0d, f_sync_type is: %0d, tst_mode is: %0d ***", width, F_SYNC_TYPE_INT, tst_mode);
|
||||
end
|
||||
`endif
|
||||
|
||||
|
||||
assign tst_mode_sel_data = (tst_mode == 1) ? test_nout1_int : data_s;
|
||||
|
||||
assign f_sync_type0_data = (test == 1'b1) ? tst_mode_sel_data : data_s;
|
||||
|
||||
assign next_data1_int = (test == 1'b0) ? data_s_int : tst_mode_sel_data;
|
||||
|
||||
|
||||
generate
|
||||
if ((f_sync_type & 7) == 1) begin : GEN_NXT_SMPL_SM1_FST_EQUAL1
|
||||
assign next_data_d2_int = ndata1_int;
|
||||
end
|
||||
if ((f_sync_type & 7) > 1) begin : GEN_NXT_SMPL_SM1_FST_GRTH1
|
||||
assign next_data_d2_int = data1_int;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @(negedge clk_d or negedge rst_d_n) begin : a1000_PROC
|
||||
if (rst_d_n === 1'b0) begin
|
||||
ndata1_int <= {width{1'b0}};
|
||||
test_nout1_int <= {width{1'b0}};
|
||||
end else if (rst_d_n === 1'b1) begin
|
||||
if (init_d_n === 1'b0) begin
|
||||
ndata1_int <= {width{1'b0}};
|
||||
test_nout1_int <= {width{1'b0}};
|
||||
end else if (init_d_n === 1'b1) begin
|
||||
ndata1_int <= data_s_int;
|
||||
test_nout1_int <= data_s;
|
||||
end else begin
|
||||
ndata1_int <= {width{1'bX}};
|
||||
test_nout1_int <= {width{1'bX}};
|
||||
end
|
||||
end else begin
|
||||
ndata1_int <= {width{1'bX}};
|
||||
test_nout1_int <= {width{1'bX}};
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_d or negedge rst_d_n) begin : a1001_PROC
|
||||
if (rst_d_n === 1'b0) begin
|
||||
data1_int <= {width{1'b0}};
|
||||
data_d2_int <= {width{1'b0}};
|
||||
data_d3_int <= {width{1'b0}};
|
||||
data_d4_int <= {width{1'b0}};
|
||||
end else if (rst_d_n === 1'b1) begin
|
||||
if (init_d_n === 1'b0) begin
|
||||
data1_int <= {width{1'b0}};
|
||||
data_d2_int <= {width{1'b0}};
|
||||
data_d3_int <= {width{1'b0}};
|
||||
data_d4_int <= {width{1'b0}};
|
||||
end else if (init_d_n === 1'b1) begin
|
||||
data1_int <= next_data1_int;
|
||||
data_d2_int <= next_data_d2_int;
|
||||
data_d3_int <= data_d2_int;
|
||||
data_d4_int <= data_d3_int;
|
||||
end else begin
|
||||
data1_int <= {width{1'bX}};
|
||||
data_d2_int <= {width{1'bX}};
|
||||
data_d3_int <= {width{1'bX}};
|
||||
data_d4_int <= {width{1'bX}};
|
||||
end
|
||||
end else begin
|
||||
data1_int <= {width{1'bX}};
|
||||
data_d2_int <= {width{1'bX}};
|
||||
data_d3_int <= {width{1'bX}};
|
||||
data_d4_int <= {width{1'bX}};
|
||||
end
|
||||
end
|
||||
|
||||
assign data_d = (F_SYNC_TYPE_INT == 0) ? f_sync_type0_data :
|
||||
(F_SYNC_TYPE_INT == 3) ? data_d3_int :
|
||||
(F_SYNC_TYPE_INT == 4) ? data_d4_int :
|
||||
data_d2_int;
|
||||
|
||||
|
||||
|
||||
always @ (clk_d) begin : monitor_clk_d
|
||||
if ( (clk_d !== 1'b0) && (clk_d !== 1'b1) && ($time > 0) )
|
||||
$display( "WARNING: %m :\n at time = %t, detected unknown value, %b, on clk_d input.",
|
||||
$time, clk_d );
|
||||
end // monitor_clk_d
|
||||
|
||||
|
||||
// synopsys translate_on
|
||||
endmodule
|
||||
/* vcs gen_ip dbg_ip off */
|
||||
/* */
|
||||
|
|
@ -0,0 +1,475 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// LVDS_DRIVER.sv
|
||||
// Enhanced LVDS Driver (4 lanes, 8 clock cycles per word)
|
||||
// Reads a 32-bit data word from a text file and sends it, providing LVDS interface driving
|
||||
// New features: automatic frame header detection, dynamic scrambler mask, CRC32 calculation, TXT frame integrity check
|
||||
// Added training sequence support (configurable pattern count)
|
||||
// Added option to ignore CRC errors (ignore_crc_error)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`ifndef LVDS_DRIVER_SV
|
||||
`define LVDS_DRIVER_SV
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// LVDS interface definition
|
||||
//-------------------------------------------------------------------------
|
||||
interface lvds_if (input bit clk);
|
||||
logic valid; // Data valid indication
|
||||
logic [3:0] data; // Data on 4 lanes
|
||||
endinterface
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// DataReader class: Reads 32-bit hexadecimal data from a file and stores it in MSB-first queue
|
||||
//-------------------------------------------------------------------------
|
||||
class DataReader;
|
||||
|
||||
bit spi_data_queue[$]; // Bit-level queue (MSB first)
|
||||
|
||||
function void read_txt_file(input string filename);
|
||||
int file_id;
|
||||
string line;
|
||||
bit [31:0] value;
|
||||
int i;
|
||||
|
||||
file_id = $fopen(filename, "r");
|
||||
if (file_id == 0) begin
|
||||
$display("Error: Failed to open file %s", filename);
|
||||
return;
|
||||
end
|
||||
|
||||
while (!$feof(file_id)) begin
|
||||
$fscanf(file_id, "%h\n", value);
|
||||
// Store the 32-bit word into queue MSB first
|
||||
for (i = 31; i >= 0; i--) begin
|
||||
spi_data_queue.push_back(value[i]);
|
||||
end
|
||||
end
|
||||
|
||||
$fclose(file_id);
|
||||
endfunction
|
||||
|
||||
function void get_data_queue(ref bit data_queue[$]);
|
||||
data_queue = spi_data_queue;
|
||||
spi_data_queue.delete();
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// lvds_item class: Encapsulates a set of 32-bit data words
|
||||
//-------------------------------------------------------------------------
|
||||
class lvds_item;
|
||||
|
||||
// Data word queue (each element 32 bits)
|
||||
bit [31:0] data[$];
|
||||
|
||||
function new(string name = "lvds_item");
|
||||
endfunction
|
||||
|
||||
// Unpack from bit stream (MSB first)
|
||||
function void unpack(ref bit stream[$]);
|
||||
bit [31:0] word;
|
||||
data.delete();
|
||||
while (stream.size() >= 32) begin
|
||||
for (int i = 0; i < 32; i++) begin
|
||||
word[31-i] = stream.pop_front();
|
||||
end
|
||||
data.push_back(word);
|
||||
end
|
||||
endfunction
|
||||
|
||||
// Pack to bit stream (MSB first)
|
||||
function void pack(ref bit stream[$]);
|
||||
foreach (data[i]) begin
|
||||
for (int j = 31; j >= 0; j--) begin
|
||||
stream.push_back(data[i][j]);
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
// Print item content (debug)
|
||||
function void print();
|
||||
$display("LVDS Item: %0d words", data.size());
|
||||
foreach (data[i]) begin
|
||||
$display(" data[%0d] = %h", i, data[i]);
|
||||
end
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// lvds_driver class: LVDS driver, supports file-driven, TB-compatible direct sending, and scrambling
|
||||
//-------------------------------------------------------------------------
|
||||
class lvds_driver;
|
||||
|
||||
// Original members
|
||||
string file_path; // Data file path
|
||||
virtual lvds_if drv_if; // Virtual interface
|
||||
int interval = 0; // Inter-word gap (clock cycles), 0 means continuous transmission
|
||||
int clk_period = 1600; // Clock period (ps), used only for debug
|
||||
|
||||
// Scrambler related members
|
||||
bit [31:0] lfsr_lane[0:3]; // Independent LFSR states for 4 lanes
|
||||
bit scrambler_en = 0; // Global scrambler enable (if set, scrambling is automatically applied during transmission)
|
||||
bit [3:0] scrambler_mask = 4'b1111; // Default scrambler mask, 1 indicates that lane is scrambled
|
||||
|
||||
// Frame header auto-detection related
|
||||
bit [31:0] frame_header = 32'hBCBCBCBC; // Default frame header
|
||||
bit auto_detect_header = 1; // Whether to auto-detect header and adjust mask
|
||||
|
||||
// Frame integrity check enable
|
||||
bit enable_frame_check = 1; // Whether to perform frame validation on file content before transmission
|
||||
bit ignore_crc_error = 1; // If set, CRC errors will be warnings (not fatal)
|
||||
|
||||
// Training related constants and variables
|
||||
const bit [31:0] TRAINING_PATN = 32'h68666E6C; // "hfnl"
|
||||
const bit [31:0] TRAINING_EXIT = 32'h65786974; // "exit"
|
||||
int train_count = 10; // Number of training pattern blocks to send (can be configured)
|
||||
|
||||
function new(string name = "lvds_driver");
|
||||
// Initialize LFSR (default uses SCRAMBLER_SEED = 32'hFFFFFFFF)
|
||||
for (int i = 0; i < 4; i++) lfsr_lane[i] = 32'hFFFFFFFF;
|
||||
endfunction
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Send a 32-bit word (fully compatible with TB approach)
|
||||
// Place the word on lane0, other lanes constant 0, send MSB first over 32 clocks
|
||||
//-------------------------------------------------------------------------
|
||||
local task send_word(bit [31:0] word);
|
||||
for (int i = 31; i >= 0; i--) begin
|
||||
@(posedge drv_if.clk);
|
||||
drv_if.valid <= 1'b1;
|
||||
drv_if.data[0] <= word[i];
|
||||
drv_if.data[3:1] <= 3'b0;
|
||||
end
|
||||
endtask
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Send an lvds_item (internally calls send_word)
|
||||
// Note: This method sends only one word on lane0 each time; for parallel transmission use send_words family tasks
|
||||
//-------------------------------------------------------------------------
|
||||
task send(lvds_item item);
|
||||
foreach (item.data[i]) begin
|
||||
send_word(item.data[i]);
|
||||
repeat (interval) @(posedge drv_if.clk);
|
||||
end
|
||||
@(posedge drv_if.clk);
|
||||
drv_if.valid <= 1'b0;
|
||||
drv_if.data <= 4'b0;
|
||||
endtask
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Send a 128-bit block, fully compatible with TB's send_block (MSB first)
|
||||
//-------------------------------------------------------------------------
|
||||
task send_block(input [127:0] block);
|
||||
for (int i = 31; i >= 0; i--) begin
|
||||
@(posedge drv_if.clk);
|
||||
drv_if.valid <= 1'b1;
|
||||
drv_if.data[0] <= block[i];
|
||||
drv_if.data[1] <= block[32 + i];
|
||||
drv_if.data[2] <= block[64 + i];
|
||||
drv_if.data[3] <= block[96 + i];
|
||||
end
|
||||
endtask
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Send multiple identical 128-bit blocks consecutively
|
||||
//-------------------------------------------------------------------------
|
||||
task send_blocks(input [127:0] block, input int count);
|
||||
repeat (count) send_block(block);
|
||||
endtask
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Send a sequence of 32-bit words (automatically pack into 128-bit blocks, zero-pad if needed)
|
||||
// Parameter words is an array, num_words is the actual number of words (up to 256)
|
||||
//-------------------------------------------------------------------------
|
||||
task send_words(input int num_words, input [31:0] words[0:255]);
|
||||
int word_idx;
|
||||
int j;
|
||||
reg [127:0] block;
|
||||
|
||||
word_idx = 0;
|
||||
while (word_idx < num_words) begin
|
||||
block = 128'h0;
|
||||
for (j = 0; j < 4; j++) begin
|
||||
if (word_idx < num_words) begin
|
||||
block[32*j +: 32] = words[word_idx];
|
||||
word_idx++;
|
||||
end
|
||||
end
|
||||
send_block(block);
|
||||
end
|
||||
endtask
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Initialize LFSR (all lanes use the same seed)
|
||||
//-------------------------------------------------------------------------
|
||||
function void init_scrambler(bit [31:0] seed);
|
||||
for (int i = 0; i < 4; i++) lfsr_lane[i] = seed;
|
||||
endfunction
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Update a single LFSR (polynomial: x^32 + x^30 + x^29 + x^28 + 1)
|
||||
//-------------------------------------------------------------------------
|
||||
function bit [31:0] lfsr_update(bit [31:0] lfsr);
|
||||
bit feedback;
|
||||
feedback = lfsr[31] ^ lfsr[30] ^ lfsr[29] ^ lfsr[28];
|
||||
lfsr_update = {lfsr[30:0], feedback};
|
||||
endfunction
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Scramble a single 128-bit block with lane mask support
|
||||
// Input original: original block; mask: whether each lane is scrambled (1=scramble)
|
||||
// Output scrambled: scrambled block
|
||||
// Note: This method updates the internal LFSR state (only for lanes that are scrambled)
|
||||
//-------------------------------------------------------------------------
|
||||
function void scramble_block_masked(input [127:0] original, input [3:0] mask, output [127:0] scrambled);
|
||||
bit [31:0] lane_word;
|
||||
scrambled = 128'h0;
|
||||
for (int i = 0; i < 4; i++) begin
|
||||
lane_word = original[32*i +: 32];
|
||||
if (mask[i]) begin
|
||||
scrambled[32*i +: 32] = lane_word ^ lfsr_lane[i];
|
||||
lfsr_lane[i] = lfsr_update(lfsr_lane[i]); // Update LFSR only for scrambled lanes
|
||||
end else begin
|
||||
scrambled[32*i +: 32] = lane_word;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Send a scrambled 128-bit block (using current scrambler_en and scrambler_mask)
|
||||
// If scrambler_en is 0, directly send the original block (same as send_block)
|
||||
//-------------------------------------------------------------------------
|
||||
task send_block_scrambled(input [127:0] block);
|
||||
if (scrambler_en) begin
|
||||
logic [127:0] scrambled;
|
||||
scramble_block_masked(block, scrambler_mask, scrambled);
|
||||
send_block(scrambled);
|
||||
end else begin
|
||||
send_block(block);
|
||||
end
|
||||
endtask
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Send a sequence of scrambled 32-bit words (using fixed scrambler_mask)
|
||||
//-------------------------------------------------------------------------
|
||||
task send_words_scrambled(input int num_words, input [31:0] words[0:255]);
|
||||
int word_idx;
|
||||
int j;
|
||||
reg [127:0] block;
|
||||
|
||||
word_idx = 0;
|
||||
while (word_idx < num_words) begin
|
||||
block = 128'h0;
|
||||
for (j = 0; j < 4; j++) begin
|
||||
if (word_idx < num_words) begin
|
||||
block[32*j +: 32] = words[word_idx];
|
||||
word_idx++;
|
||||
end
|
||||
end
|
||||
send_block_scrambled(block);
|
||||
end
|
||||
endtask
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Frame check function, verifies if words form a valid frame (header, length, CRC)
|
||||
// Returns 1 for pass, 0 for fail, err_msg outputs error information
|
||||
//-------------------------------------------------------------------------
|
||||
static function bit check_frame(bit [31:0] words[$], ref string err_msg);
|
||||
int num_words = words.size();
|
||||
bit [31:0] header, addr_len, crc_expected, crc_computed;
|
||||
int data_len;
|
||||
bit [31:0] data_words[0:255]; // For CRC calculation
|
||||
int i;
|
||||
|
||||
// Basic length check: at least 3 words (header, addr/len, CRC)
|
||||
if (num_words < 3) begin
|
||||
err_msg = "Frame word count less than 3";
|
||||
return 0;
|
||||
end
|
||||
|
||||
header = words[0];
|
||||
if (header !== 32'hBCBCBCBC) begin
|
||||
err_msg = $sformatf("Frame header error, expected 32'hBCBCBCBC, got 32'h%h", header);
|
||||
return 0;
|
||||
end
|
||||
|
||||
addr_len = words[1];
|
||||
data_len = addr_len[15:0]; // Lower 16 bits are data length
|
||||
// Verify total word count: 1(header) + 1(addr/len) + data_len + 1(CRC) = 3 + data_len
|
||||
if (num_words != 3 + data_len) begin
|
||||
err_msg = $sformatf("Frame length mismatch: expected %0d words from length field, got %0d words", 3+data_len, num_words);
|
||||
return 0;
|
||||
end
|
||||
|
||||
// Collect data part (addr_len word + data words) for CRC calculation
|
||||
// Note: CRC range is from words[1] to words[1+data_len-1] (total 1+data_len words)
|
||||
for (i = 0; i < 1+data_len; i++) begin
|
||||
data_words[i] = words[1 + i];
|
||||
end
|
||||
crc_computed = crc32_compute(data_words, 1+data_len);
|
||||
crc_expected = words[2+data_len]; // CRC word
|
||||
|
||||
if (crc_computed !== crc_expected) begin
|
||||
err_msg = $sformatf("CRC error: computed 32'h%h, expected 32'h%h", crc_computed, crc_expected);
|
||||
return 0;
|
||||
end
|
||||
|
||||
err_msg = "Frame check passed";
|
||||
return 1;
|
||||
endfunction
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Read complete frame data from file, auto-detect frame header and dynamically adjust scrambler mask
|
||||
// The lane containing the frame header is not scrambled, other lanes are scrambled; all subsequent blocks are fully scrambled
|
||||
// Perform frame integrity check before transmission (if enable_frame_check is 1)
|
||||
//-------------------------------------------------------------------------
|
||||
task send_frame_from_file(string filename);
|
||||
DataReader reader = new();
|
||||
bit bit_stream[$];
|
||||
lvds_item item = new();
|
||||
string err_msg;
|
||||
reader.read_txt_file(filename);
|
||||
reader.get_data_queue(bit_stream);
|
||||
item.unpack(bit_stream);
|
||||
|
||||
// Frame check
|
||||
if (enable_frame_check) begin
|
||||
if (!check_frame(item.data, err_msg)) begin
|
||||
if (ignore_crc_error) begin
|
||||
$warning("Frame check warning: %s, file %s (ignored)", err_msg, filename);
|
||||
end else begin
|
||||
$error("Frame check failed: %s, file %s", err_msg, filename);
|
||||
return; // Stop transmission
|
||||
end
|
||||
end else begin
|
||||
$display("Frame check passed: %s", err_msg);
|
||||
end
|
||||
end
|
||||
|
||||
send_words_scrambled_auto(item.data);
|
||||
endtask
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Send word queue, auto-detect frame header and dynamically adjust scrambler mask
|
||||
// If auto_detect_header is 0 or scrambler_en is 0, use fixed mask (scrambler_mask)
|
||||
// Otherwise, detect per block; when header is encountered, set that lane mask to 0, subsequent blocks all 1
|
||||
//-------------------------------------------------------------------------
|
||||
task send_words_scrambled_auto(bit [31:0] words[$]);
|
||||
int word_idx;
|
||||
int block_idx;
|
||||
bit header_found;
|
||||
reg [127:0] block;
|
||||
bit [3:0] mask;
|
||||
int num;
|
||||
bit [31:0] words_arr[0:255];
|
||||
|
||||
if (!scrambler_en || !auto_detect_header) begin
|
||||
// Fallback to fixed mask transmission
|
||||
num = words.size();
|
||||
foreach (words[i]) words_arr[i] = words[i];
|
||||
send_words_scrambled(num, words_arr);
|
||||
return;
|
||||
end
|
||||
|
||||
// Auto-detection mode
|
||||
word_idx = 0;
|
||||
block_idx = 0;
|
||||
header_found = 0;
|
||||
|
||||
while (word_idx < words.size()) begin
|
||||
// Pack current block (up to 4 words)
|
||||
block = 128'h0;
|
||||
for (int j = 0; j < 4; j++) begin
|
||||
if (word_idx < words.size()) begin
|
||||
block[32*j +: 32] = words[word_idx];
|
||||
word_idx++;
|
||||
end
|
||||
end
|
||||
|
||||
// Determine scrambler mask for current block
|
||||
if (!header_found) begin
|
||||
mask = 4'b1111; // Default all scrambled
|
||||
// Check if current block contains the frame header
|
||||
for (int j = 0; j < 4; j++) begin
|
||||
if (word_idx - 4 + j < words.size()) begin // Ensure index is valid
|
||||
if (block[32*j +: 32] == frame_header) begin
|
||||
mask[j] = 1'b0; // Lane containing header is not scrambled
|
||||
header_found = 1;
|
||||
// Note: Even if multiple headers appear in one block (theoretically impossible), we handle only the first
|
||||
end
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
mask = 4'b1111; // Header already found, subsequent blocks all scrambled
|
||||
end
|
||||
|
||||
// Send current block (scrambled according to mask)
|
||||
if (scrambler_en) begin
|
||||
logic [127:0] scrambled;
|
||||
scramble_block_masked(block, mask, scrambled);
|
||||
send_block(scrambled);
|
||||
end else begin
|
||||
send_block(block);
|
||||
end
|
||||
block_idx++;
|
||||
end
|
||||
endtask
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Main driving task: Read data from file and send (using full parallel 128-bit scrambled transmission)
|
||||
// Automatically detect frame header and apply scrambler mask (if scrambler enabled)
|
||||
//-------------------------------------------------------------------------
|
||||
task do_drive();
|
||||
send_frame_from_file(file_path);
|
||||
endtask
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Send training sequence: train_count blocks of TRAINING_PATN, then one block of TRAINING_EXIT
|
||||
// Optionally disable scrambling during training
|
||||
//-------------------------------------------------------------------------
|
||||
task send_training();
|
||||
bit [127:0] train_block = {4{TRAINING_PATN}};
|
||||
bit [127:0] exit_block = {4{TRAINING_EXIT}};
|
||||
bit prev_scrambler_en = scrambler_en;
|
||||
scrambler_en = 0; // Training patterns are not scrambled
|
||||
send_blocks(train_block, train_count);
|
||||
send_block(exit_block);
|
||||
scrambler_en = prev_scrambler_en;
|
||||
endtask
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Optional: Combined task to send training then data frame
|
||||
//-------------------------------------------------------------------------
|
||||
task send_training_and_data(string filename);
|
||||
send_training();
|
||||
send_frame_from_file(filename);
|
||||
endtask
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// CRC32 calculation functions (polynomial 0x04C11DB7, initial value 0xFFFFFFFF)
|
||||
//-------------------------------------------------------------------------
|
||||
static function automatic bit [31:0] crc32_next(input bit [31:0] crc, input bit [31:0] data);
|
||||
bit [31:0] new_crc;
|
||||
bit b;
|
||||
new_crc = crc;
|
||||
for (int i = 0; i < 32; i++) begin
|
||||
b = new_crc[31] ^ data[31-i];
|
||||
new_crc = {new_crc[30:0], 1'b0};
|
||||
if (b) new_crc = new_crc ^ 32'h04C11DB7;
|
||||
end
|
||||
return new_crc;
|
||||
endfunction
|
||||
|
||||
static function automatic bit [31:0] crc32_compute(input bit [31:0] words[0:255], input int num);
|
||||
bit [31:0] crc = 32'hFFFFFFFF;
|
||||
for (int i = 0; i < num; i++) begin
|
||||
crc = crc32_next(crc, words[i]);
|
||||
end
|
||||
return crc;
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
`endif // LVDS_DRIVER_SV
|
||||
|
|
@ -0,0 +1,424 @@
|
|||
//top-class : spi_driver
|
||||
//parameter : file_path: the path of *.txt file
|
||||
// itf: spi interface (type==spi_if)
|
||||
// half_sclk(option): =(half period of sclk)/(period of clk), default 5
|
||||
// interval(option): the time to wait between the adjacent W/R operation/(period of clk), defaut 10
|
||||
//example case :
|
||||
/* spi_driver my_drv;
|
||||
|
||||
initial begin
|
||||
|
||||
my_drv = new();
|
||||
|
||||
my_drv.file_path = "./../cfgdata/enveindex/wave_index_13.txt";
|
||||
my_drv.itf = my_if;
|
||||
my_drv.half_sclk = 10;
|
||||
my_drv.interval = 50;
|
||||
|
||||
my_drv.do_drive();
|
||||
|
||||
end//*/
|
||||
|
||||
class BinaryDataReader;
|
||||
|
||||
// data_stream
|
||||
bit spi_data_queue[$];
|
||||
int cmd_head[$];
|
||||
|
||||
// open & read txt_file
|
||||
function void read_txt_file(input string filename);
|
||||
int file_id;
|
||||
string line;
|
||||
bit [31:0] value;
|
||||
int i;
|
||||
//int cmd_head[$];
|
||||
int length;
|
||||
bit cmd;
|
||||
int cnt;
|
||||
|
||||
// open
|
||||
file_id = $fopen(filename, "r");
|
||||
if (file_id == 0) begin
|
||||
$display("Error: Failed to open file %s", filename);
|
||||
return;
|
||||
end
|
||||
|
||||
cnt = 0;
|
||||
// read
|
||||
while (!$feof(file_id)) begin
|
||||
//if ($fgets(line, file_id)) begin
|
||||
$fscanf(file_id,"%h\n",value);
|
||||
//$display("\nvalue = %h",value);
|
||||
//$display("cnt = %h",cnt);
|
||||
if(cnt == 0) begin
|
||||
cmd = value[31];
|
||||
|
||||
if(cmd) cmd_head.push_back(value);
|
||||
|
||||
cnt ++;
|
||||
end
|
||||
else if(cnt == 1) begin
|
||||
if(cmd) cmd_head.push_back(value);
|
||||
|
||||
length = value[15:0] / 4;
|
||||
|
||||
if(!cmd) cnt ++;
|
||||
else cnt = 0;
|
||||
end
|
||||
else if((cnt == length-1 +2) | cmd) begin
|
||||
cnt = 0;
|
||||
end
|
||||
else begin
|
||||
cnt ++;
|
||||
end
|
||||
//$display("cmd = %h",cmd);
|
||||
//$display("length = %h",length);
|
||||
//$display(cmd_head);
|
||||
|
||||
for (i = 31; i >= 0; i--) begin
|
||||
spi_data_queue.push_back(value[i]);
|
||||
end
|
||||
//end
|
||||
end
|
||||
|
||||
|
||||
// close
|
||||
$fclose(file_id);
|
||||
endfunction
|
||||
|
||||
function void get_data_queue(ref bit data_queue[$]);
|
||||
data_queue = spi_data_queue;
|
||||
spi_data_queue.delete();
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class spi_item;
|
||||
|
||||
//Properties for Randomizing the MOSI
|
||||
rand bit cmd;
|
||||
rand bit[24:0] addr;
|
||||
rand bit[ 4:0] cfgid;
|
||||
rand bit[31:0] data[$];
|
||||
|
||||
//Properties for Randomizing the pkt_sent process
|
||||
rand int interval;
|
||||
rand int half_sclk;
|
||||
|
||||
constraint cstr {
|
||||
interval <= 1000;
|
||||
half_sclk >= 5;
|
||||
data.size >= 1;
|
||||
data.size <= 10000;
|
||||
}
|
||||
|
||||
function new(string name="spi_item");
|
||||
endfunction : new
|
||||
|
||||
extern function bit compare(spi_item rhs_);
|
||||
extern function void print();
|
||||
extern function void fprint(integer fid);
|
||||
extern function void trprint(integer fid, ref int cmd_head[$]);
|
||||
extern function void unpack(ref bit stream[$]);
|
||||
extern function void pack(bit stream[$]);
|
||||
extern function void adapt(
|
||||
ref bit stream[$]
|
||||
, int half_sclk
|
||||
, int interval
|
||||
);
|
||||
|
||||
endclass : spi_item
|
||||
|
||||
|
||||
|
||||
function bit spi_item::compare(spi_item rhs_);
|
||||
bit result=1'b1;
|
||||
int i=0;
|
||||
|
||||
if(this.data.size() != rhs_.data.size()) begin
|
||||
$display("data_sizes are different");
|
||||
result = 1'b0;
|
||||
end
|
||||
else begin
|
||||
for(i=0;i<data.size();i++)begin
|
||||
if(data[i] != rhs_.data[i])
|
||||
result = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
return result;
|
||||
endfunction : compare
|
||||
|
||||
|
||||
function void spi_item::print();
|
||||
int i=0;
|
||||
if(!cmd)$display("----------ONE-PKT-DRIVING----------");
|
||||
else $display("---------ONE-PKT-COLLECTING--------");
|
||||
$display("cmd:\t%h",cmd);
|
||||
$display("addr:\t%h",addr);
|
||||
$display("cfgid:\t%h",cfgid);
|
||||
for(i=0;i<data.size();i++)begin
|
||||
$display("data[%2d]='h%h",i,data[i]);
|
||||
end
|
||||
$display("-----------------------------------");
|
||||
endfunction : print
|
||||
|
||||
|
||||
function void spi_item::unpack(ref bit stream[$]);
|
||||
int i=0,j=0;
|
||||
|
||||
stream[0]=cmd;
|
||||
|
||||
for(i=0;i<25;i++)
|
||||
stream[i+1] = addr[24-i];
|
||||
|
||||
for(i=0;i<5;i++)
|
||||
stream[i+26]= cfgid[4-i];
|
||||
|
||||
stream[31]=0;
|
||||
|
||||
for(i=0;i<data.size();i++)begin
|
||||
//$display("i=%2d,datai=%b",i,data[i]);
|
||||
for(j=0;j<32;j++)begin
|
||||
stream[32+i*32+j]=data[i][31-j];
|
||||
//$display("i=%2d,j=%2d,streamij=%b",i,j,stream[32+i*32+j]);
|
||||
end
|
||||
end
|
||||
|
||||
endfunction
|
||||
|
||||
|
||||
function void spi_item::fprint(integer fid);
|
||||
int i=0;
|
||||
if(!cmd)$fwrite(fid,"----------ONE-PKT-DRIVING----------\n");
|
||||
else $fwrite(fid,"---------ONE-PKT-COLLECTING--------\n");
|
||||
$fwrite(fid,"cmd:\t%h\n",cmd);
|
||||
$fwrite(fid,"addr:\t%h\n",addr);
|
||||
$fwrite(fid,"length:\t%d\n",data.size());
|
||||
for(i=0;i<data.size();i++)begin
|
||||
$fwrite(fid,"%h\n",data[i]);
|
||||
end
|
||||
$fwrite(fid,"-----------------------------------\n");
|
||||
endfunction : fprint
|
||||
|
||||
function void spi_item::trprint(integer fid, ref int cmd_head[$]);
|
||||
int i=0;
|
||||
$fwrite(fid,"---------ONE-PKT-COLLECTING--------\n");
|
||||
$fwrite(fid,"%h\n",cmd_head.pop_front());
|
||||
$fwrite(fid,"%h\n",cmd_head.pop_front());
|
||||
for(i=0;i<data.size();i++)begin
|
||||
$fwrite(fid,"%h\n",data[i]);
|
||||
end
|
||||
$fwrite(fid,"-----------------------------------\n");
|
||||
endfunction : trprint
|
||||
|
||||
|
||||
function void spi_item::pack(bit stream[$]);
|
||||
int i=0;
|
||||
bit[31:0] data_temp=32'b0;
|
||||
|
||||
//$display(stream);
|
||||
|
||||
cmd = stream.pop_front();
|
||||
|
||||
for(i=0;i<25;i++)
|
||||
addr[24-i] = stream.pop_front();
|
||||
|
||||
for(i=0;i<5;i++)
|
||||
cfgid[4-i] = stream.pop_front();
|
||||
|
||||
//reserved
|
||||
stream.pop_front();
|
||||
|
||||
data.delete();
|
||||
while(stream.size()>0)begin
|
||||
for(i=0;i<32;i++)
|
||||
data_temp[31-i] = stream.pop_front();
|
||||
data.push_back(data_temp);
|
||||
end
|
||||
|
||||
endfunction
|
||||
|
||||
function void spi_item::adapt(ref bit stream[$], int half_sclk, int interval);
|
||||
int i=0;
|
||||
bit[31:0] data_length=32'b0;
|
||||
bit[31:0] data_temp=32'b0;
|
||||
|
||||
cmd = stream.pop_front();
|
||||
|
||||
//reserved
|
||||
stream.pop_front();
|
||||
|
||||
for(i=0;i<5;i++)
|
||||
cfgid[4-i] = stream.pop_front();
|
||||
|
||||
for(i=0;i<25;i++)
|
||||
addr[24-i] = stream.pop_front();
|
||||
|
||||
for(i=0;i<32;i++)
|
||||
data_length[31-i] = stream.pop_front();
|
||||
data_length = {14'b0,data_length[19:2]};
|
||||
|
||||
repeat(data_length) begin
|
||||
for(i=0;i<32;i++)
|
||||
data_temp[31-i] = cmd ? 1'b0 : stream.pop_front();
|
||||
data.push_back(data_temp);
|
||||
end
|
||||
|
||||
this.half_sclk = half_sclk;
|
||||
this.interval = interval;
|
||||
endfunction
|
||||
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
class spi_driver;
|
||||
|
||||
string file_path;
|
||||
virtual spi_if itf;
|
||||
int interval = 10;
|
||||
int half_sclk = 5 ;
|
||||
|
||||
spi_item m_trans;
|
||||
|
||||
/*static string file_list[$]={
|
||||
"./../cfgdata/instrmem/awg_inst.txt" //0
|
||||
,"./../cfgdata/instrmem/LongFlattop_bin.txt" //1
|
||||
,"./../cfgdata/instrmem/LongFlattopAmpAdj_bin.txt" //2
|
||||
,"./../cfgdata/instrmem/LongRectangle_bin.txt" //3
|
||||
,"./../cfgdata/instrmem/LongRectangle50us_bin.txt" //4
|
||||
,"./../cfgdata/instrmem/SingleWaveACCZ_bin.txt" //5
|
||||
,"./../cfgdata/instrmem/SingleWaveCombine_bin.txt" //6
|
||||
,"./../cfgdata/instrmem/SingleWaveCosine_bin.txt" //7
|
||||
,"./../cfgdata/instrmem/SingleWaveFlattop_bin.txt" //8
|
||||
,"./../cfgdata/instrmem/SingleWaveRectangle_bin.txt" //9
|
||||
,"./../cfgdata/instrmem/WaveHold_bin.txt" //10
|
||||
,"./../cfgdata/instrmem/Condition_bin.txt" //11
|
||||
,"./../cfgdata/instrmem/RabiFreqAmp_bin.txt" //12
|
||||
,"./../cfgdata/instrmem/WaveHoldSingle_bin.txt" //13
|
||||
,"./../cfgdata/instrmem/Cosine9_bin.txt" //14
|
||||
//,"./../cfgdata/datamem/data_mem.txt" //15
|
||||
,"./../cfgdata/datamem/Cosine9_data_bin.txt" //15
|
||||
//,"./../cfgdata/enveindex/enve_index.txt" //16
|
||||
,"./../cfgdata/enveindex/wave_index_13.txt" //16
|
||||
//,"./../cfgdata/envemem/envelop_mem.txt" //17
|
||||
,"./../cfgdata/envemem/wave_bin_13.txt" //17
|
||||
,"./../cfgdata/envemem/rwave_bin_12.txt" //18
|
||||
};//*/
|
||||
|
||||
|
||||
function new(string name = "spi_seq");
|
||||
endfunction : new
|
||||
|
||||
extern task send(ref spi_item pkt);
|
||||
|
||||
task do_drive(integer o_file_path=0);
|
||||
|
||||
BinaryDataReader reader = new();
|
||||
//spi_item m_trans;
|
||||
bit stream[$];
|
||||
|
||||
reader.read_txt_file(file_path);
|
||||
reader.get_data_queue(stream);
|
||||
//$display(stream);
|
||||
while(stream.size()>0) begin
|
||||
//$display(stream.size());
|
||||
m_trans = new("m_trans");
|
||||
m_trans.adapt(stream,half_sclk,interval);
|
||||
//m_trans.print();
|
||||
send(m_trans);
|
||||
m_trans.print();
|
||||
if(o_file_path!=0) begin
|
||||
//m_trans.fprint(o_file_path);
|
||||
if(m_trans.cmd) begin
|
||||
m_trans.trprint(o_file_path, reader.cmd_head);
|
||||
end
|
||||
end
|
||||
end
|
||||
endtask : do_drive
|
||||
|
||||
endclass : spi_driver
|
||||
|
||||
|
||||
task spi_driver::send(ref spi_item pkt);
|
||||
bit drv_stream[$];
|
||||
bit clt_stream[$];
|
||||
int i=0,j=0;
|
||||
int cs_time;
|
||||
int hs = pkt.half_sclk;
|
||||
|
||||
while(!itf.rstn) begin
|
||||
itf.csn = 1'b1;
|
||||
itf.sclk = 1'b1;
|
||||
@(posedge itf.clk);
|
||||
end
|
||||
//$display("unpacking");
|
||||
//unpack into bitstream
|
||||
pkt.unpack(drv_stream);
|
||||
//$display(stream);
|
||||
//$display("unpackend");
|
||||
//initialize chip_select and input_clk
|
||||
itf.csn <= 1'b1;
|
||||
itf.sclk <= 1'b1;
|
||||
itf.mosi <= drv_stream[0];
|
||||
itf.cfgid <= pkt.cfgid;
|
||||
@(posedge itf.clk);
|
||||
itf.csn <= 1'b0;
|
||||
itf.sclk <= 1'b1;
|
||||
//$display("initialize end");
|
||||
//csn valid time: time for bitstream to be all sent
|
||||
cs_time = drv_stream.size()*2*hs;
|
||||
//$display(stream.size());
|
||||
//$display("drv_stream.size = %0d", drv_stream.size());
|
||||
//$display(cs_time);
|
||||
//drive the stream onto interface
|
||||
fork
|
||||
//Make sclk
|
||||
begin
|
||||
for(j=0;j<cs_time;j++) begin
|
||||
if(j%hs==0 && j!=0)
|
||||
itf.sclk <= ~itf.sclk;
|
||||
@(posedge itf.clk);
|
||||
//$display("j = %0d", j);
|
||||
end
|
||||
itf.sclk = 1'b1;
|
||||
repeat(4) @(posedge itf.clk);
|
||||
itf.csn = 1'b1;
|
||||
end
|
||||
|
||||
//Send data(at negedge)
|
||||
begin
|
||||
|
||||
for(i=0;i<=cs_time;i++) begin
|
||||
// Drive at negedge
|
||||
if(i%(2*hs)==hs) begin
|
||||
itf.mosi <= drv_stream[(i/hs-1)/2];
|
||||
end
|
||||
// Collect at posedge
|
||||
else if(i%(2*hs)==0 && i!=0) begin
|
||||
clt_stream.push_back(pkt.cmd ? itf.miso : itf.mosi);
|
||||
//$write(itf.mosi);
|
||||
end
|
||||
@(posedge itf.clk);
|
||||
end
|
||||
//clt_stream collect the read_data/write_data, and
|
||||
//the first 32bit should be consistent to the input command word
|
||||
for(i=0;i<32;i++) clt_stream[i]=drv_stream[i];
|
||||
//$display(clt_stream);
|
||||
//$display("i = %0d", i);
|
||||
|
||||
pkt.pack(clt_stream);
|
||||
|
||||
end
|
||||
|
||||
join
|
||||
|
||||
//interval between two pkt send operation
|
||||
repeat(pkt.interval-1)
|
||||
@(posedge itf.clk);
|
||||
|
||||
endtask
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
module clk_gen(
|
||||
input rstn,
|
||||
input clk,
|
||||
output clk_div16_0,
|
||||
output clk_div16_1,
|
||||
output clk_div16_2,
|
||||
output clk_div16_3,
|
||||
output clk_div16_4,
|
||||
output clk_div16_5,
|
||||
output clk_div16_6,
|
||||
output clk_div16_7,
|
||||
output clk_div16_8,
|
||||
output clk_div16_9,
|
||||
output clk_div16_a,
|
||||
output clk_div16_b,
|
||||
output clk_div16_c,
|
||||
output clk_div16_d,
|
||||
output clk_div16_e,
|
||||
output clk_div16_f,
|
||||
|
||||
output clk_h,
|
||||
output clk_l
|
||||
);
|
||||
|
||||
reg [3:0] cnt_ini;
|
||||
always@(posedge clk or negedge rstn)
|
||||
if(!rstn)
|
||||
cnt_ini <= 4'd0;
|
||||
else if(cnt_ini <= 4'd7)
|
||||
cnt_ini <= cnt_ini + 4'd1;
|
||||
else
|
||||
cnt_ini <= cnt_ini;
|
||||
wire div_en;
|
||||
assign div_en = (cnt_ini ==4'd8)? 1'b1:1'b0;
|
||||
|
||||
reg [3:0] cnt_0;
|
||||
reg [3:0] cnt_1;
|
||||
reg [3:0] cnt_2;
|
||||
reg [3:0] cnt_3;
|
||||
reg [3:0] cnt_4;
|
||||
reg [3:0] cnt_5;
|
||||
reg [3:0] cnt_6;
|
||||
reg [3:0] cnt_7;
|
||||
reg [3:0] cnt_8;
|
||||
reg [3:0] cnt_9;
|
||||
reg [3:0] cnt_a;
|
||||
reg [3:0] cnt_b;
|
||||
reg [3:0] cnt_c;
|
||||
reg [3:0] cnt_d;
|
||||
reg [3:0] cnt_e;
|
||||
reg [3:0] cnt_f;
|
||||
|
||||
always@(posedge clk or negedge rstn)
|
||||
if(!rstn) begin
|
||||
cnt_0 <= 4'h0;
|
||||
cnt_1 <= 4'h1;
|
||||
cnt_2 <= 4'h2;
|
||||
cnt_3 <= 4'h3;
|
||||
cnt_4 <= 4'h4;
|
||||
cnt_5 <= 4'h5;
|
||||
cnt_6 <= 4'h6;
|
||||
cnt_7 <= 4'h7;
|
||||
cnt_8 <= 4'h8;
|
||||
cnt_9 <= 4'h9;
|
||||
cnt_a <= 4'ha;
|
||||
cnt_b <= 4'hb;
|
||||
cnt_c <= 4'hc;
|
||||
cnt_d <= 4'hd;
|
||||
cnt_e <= 4'he;
|
||||
cnt_f <= 4'hf;
|
||||
end
|
||||
else if(div_en) begin
|
||||
cnt_0 <= cnt_0 + 4'd1;
|
||||
cnt_1 <= cnt_1 + 4'd1;
|
||||
cnt_2 <= cnt_2 + 4'd1;
|
||||
cnt_3 <= cnt_3 + 4'd1;
|
||||
cnt_4 <= cnt_4 + 4'd1;
|
||||
cnt_5 <= cnt_5 + 4'd1;
|
||||
cnt_6 <= cnt_6 + 4'd1;
|
||||
cnt_7 <= cnt_7 + 4'd1;
|
||||
cnt_8 <= cnt_8 + 4'd1;
|
||||
cnt_9 <= cnt_9 + 4'd1;
|
||||
cnt_a <= cnt_a + 4'd1;
|
||||
cnt_b <= cnt_b + 4'd1;
|
||||
cnt_c <= cnt_c + 4'd1;
|
||||
cnt_d <= cnt_d + 4'd1;
|
||||
cnt_e <= cnt_e + 4'd1;
|
||||
cnt_f <= cnt_f + 4'd1;
|
||||
end
|
||||
else begin
|
||||
cnt_0 <= cnt_0;
|
||||
cnt_1 <= cnt_1;
|
||||
cnt_2 <= cnt_2;
|
||||
cnt_3 <= cnt_3;
|
||||
cnt_4 <= cnt_4;
|
||||
cnt_5 <= cnt_5;
|
||||
cnt_6 <= cnt_6;
|
||||
cnt_7 <= cnt_7;
|
||||
cnt_8 <= cnt_8;
|
||||
cnt_9 <= cnt_9;
|
||||
cnt_a <= cnt_a;
|
||||
cnt_b <= cnt_b;
|
||||
cnt_c <= cnt_c;
|
||||
cnt_d <= cnt_d;
|
||||
cnt_e <= cnt_e;
|
||||
cnt_f <= cnt_f;
|
||||
|
||||
end
|
||||
|
||||
assign clk_div16_0 = cnt_0[3];
|
||||
assign clk_div16_1 = cnt_1[3];
|
||||
assign clk_div16_2 = cnt_2[3];
|
||||
assign clk_div16_3 = cnt_3[3];
|
||||
assign clk_div16_4 = cnt_4[3];
|
||||
assign clk_div16_5 = cnt_5[3];
|
||||
assign clk_div16_6 = cnt_6[3];
|
||||
assign clk_div16_7 = cnt_7[3];
|
||||
assign clk_div16_8 = cnt_8[3];
|
||||
assign clk_div16_9 = cnt_9[3];
|
||||
assign clk_div16_a = cnt_a[3];
|
||||
assign clk_div16_b = cnt_b[3];
|
||||
assign clk_div16_c = cnt_c[3];
|
||||
assign clk_div16_d = cnt_d[3];
|
||||
assign clk_div16_e = cnt_e[3];
|
||||
assign clk_div16_f = cnt_f[3];
|
||||
|
||||
|
||||
reg [3:0] cnt_div16;
|
||||
always@(posedge clk_div16_0 or negedge rstn)
|
||||
if(!rstn)
|
||||
cnt_div16 <= 4'd0;
|
||||
else if(div_en)
|
||||
cnt_div16 <= cnt_div16 + 4'd1;
|
||||
else
|
||||
cnt_div16 <= cnt_div16;
|
||||
|
||||
|
||||
assign clk_h = clk_div16_0;
|
||||
assign clk_l = cnt_div16[0];
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
`timescale 1ns / 1ps
|
||||
|
||||
module clock_tb #(
|
||||
parameter PERIOD = 4,
|
||||
parameter PHASE = 0
|
||||
)(
|
||||
output clk_out
|
||||
);
|
||||
reg clk;
|
||||
|
||||
initial begin
|
||||
//#PHASE clk = 0;
|
||||
clk = 0;
|
||||
forever #(PERIOD/2.0) clk = ~clk;
|
||||
end
|
||||
assign clk_out = clk;
|
||||
endmodule
|
||||
/* HIDE```*/
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/glbl.v,v 1.14 2010/10/28 20:44:00 fphillip Exp $
|
||||
`ifndef GLBL
|
||||
`define GLBL
|
||||
`timescale 1 ps / 1 ps
|
||||
|
||||
module glbl ();
|
||||
|
||||
parameter ROC_WIDTH = 100000;
|
||||
parameter TOC_WIDTH = 0;
|
||||
|
||||
//-------- STARTUP Globals --------------
|
||||
wire GSR;
|
||||
wire GTS;
|
||||
wire GWE;
|
||||
wire PRLD;
|
||||
tri1 p_up_tmp;
|
||||
tri (weak1, strong0) PLL_LOCKG = p_up_tmp;
|
||||
|
||||
wire PROGB_GLBL;
|
||||
wire CCLKO_GLBL;
|
||||
wire FCSBO_GLBL;
|
||||
wire [3:0] DO_GLBL;
|
||||
wire [3:0] DI_GLBL;
|
||||
|
||||
reg GSR_int;
|
||||
reg GTS_int;
|
||||
reg PRLD_int;
|
||||
|
||||
//-------- JTAG Globals --------------
|
||||
wire JTAG_TDO_GLBL;
|
||||
wire JTAG_TCK_GLBL;
|
||||
wire JTAG_TDI_GLBL;
|
||||
wire JTAG_TMS_GLBL;
|
||||
wire JTAG_TRST_GLBL;
|
||||
|
||||
reg JTAG_CAPTURE_GLBL;
|
||||
reg JTAG_RESET_GLBL;
|
||||
reg JTAG_SHIFT_GLBL;
|
||||
reg JTAG_UPDATE_GLBL;
|
||||
reg JTAG_RUNTEST_GLBL;
|
||||
|
||||
reg JTAG_SEL1_GLBL = 0;
|
||||
reg JTAG_SEL2_GLBL = 0 ;
|
||||
reg JTAG_SEL3_GLBL = 0;
|
||||
reg JTAG_SEL4_GLBL = 0;
|
||||
|
||||
reg JTAG_USER_TDO1_GLBL = 1'bz;
|
||||
reg JTAG_USER_TDO2_GLBL = 1'bz;
|
||||
reg JTAG_USER_TDO3_GLBL = 1'bz;
|
||||
reg JTAG_USER_TDO4_GLBL = 1'bz;
|
||||
|
||||
assign (strong1, weak0) GSR = GSR_int;
|
||||
assign (strong1, weak0) GTS = GTS_int;
|
||||
assign (weak1, weak0) PRLD = PRLD_int;
|
||||
|
||||
initial begin
|
||||
GSR_int = 1'b1;
|
||||
PRLD_int = 1'b1;
|
||||
#(ROC_WIDTH)
|
||||
GSR_int = 1'b0;
|
||||
PRLD_int = 1'b0;
|
||||
end
|
||||
|
||||
initial begin
|
||||
GTS_int = 1'b1;
|
||||
#(TOC_WIDTH)
|
||||
GTS_int = 1'b0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
`endif
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/* HIDE <!----------------------------------------------------------------------------->
|
||||
[comment]: <> (Verilog template v0.03)
|
||||
|
||||
## Project Information
|
||||
| > | Project Name | > | File Name |
|
||||
| :-: | :-: | :-: | :-: |
|
||||
| > | TODO | > | TODO |
|
||||
| **Engineer** | **Institution** | **Target Devices** | **Tool Versions** |
|
||||
| Guo Cheng[^1] | USTC | XC6VLX240TFF1156 | Xilinx ISE 13.3 |
|
||||
| **Dependencies** | > | > | TODO |
|
||||
| **Descriptions** | > | > | TODO |
|
||||
[^1]: Author E-mail: <fortune@mail.ustc.edu.cn>
|
||||
|
||||
## Reversion Information
|
||||
| Revision | Time | Comments |
|
||||
| :-: | :-: | :-: |
|
||||
| ==v0.01== | 2019-08-08T02:51:47.205Z | File Create |
|
||||
|
||||
## Code Segments
|
||||
<!----------------------------------------------------------------------------------> */
|
||||
|
||||
/* HIDE```verilog{.line-numbers}*/
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module reset_tb #(
|
||||
parameter DELAY = 0,
|
||||
parameter POLAR = 0,
|
||||
parameter WIDTH = 4
|
||||
)(
|
||||
output reset_out
|
||||
);
|
||||
reg reset;
|
||||
|
||||
initial begin
|
||||
reset = !POLAR;
|
||||
#DELAY reset = POLAR;
|
||||
#WIDTH reset = !POLAR;
|
||||
end
|
||||
assign reset_out = reset;
|
||||
endmodule
|
||||
/* HIDE```*/
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
|
||||
interface spi_if(input bit clk,input bit rstn);
|
||||
|
||||
logic sclk ;
|
||||
logic csn ;
|
||||
logic mosi ;
|
||||
logic miso ;
|
||||
logic[4 : 0] cfgid ;
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
//+FHDR--------------------------------------------------------------------------------------------------------
|
||||
// Company:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// File Name : awg_ctrl.v
|
||||
// Department :
|
||||
// Author : hdzhang
|
||||
// Author's Tel :
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Relese History
|
||||
// Version Date Author Description
|
||||
// 0.1 2026-02-28 hdzhang fifo-cmd controlled waveform output
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Keywords :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Parameter
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Target Device:
|
||||
// Tool versions:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Reuse Issues
|
||||
// Reset Strategy:
|
||||
// Clock Domains:
|
||||
// Critical Timing:
|
||||
// Asynchronous I/F:
|
||||
// Synthesizable (y/n):
|
||||
// Other:
|
||||
//-FHDR--------------------------------------------------------------------------------------------------------
|
||||
|
||||
module awg_ctrl (
|
||||
//system port
|
||||
input clk // System Main Clock
|
||||
,input rst_n // Spi Reset active low
|
||||
//sync signal
|
||||
,input start
|
||||
//cmd fifo read signal
|
||||
,output cmd_fifo_rd_en
|
||||
,input [31 :0] cmd_fifo_data
|
||||
,input cmd_fifo_empty
|
||||
//wave sram read signals
|
||||
,output sram_rd_en
|
||||
,output [12 :0] sram_rd_addr
|
||||
,input [511:0] sram_rd_data
|
||||
//output to dem module
|
||||
,output [511:0] wave_data_out
|
||||
,output wave_valid_out
|
||||
//state submit
|
||||
,output [2 :0] status
|
||||
,output wave_busy
|
||||
);
|
||||
|
||||
localparam IDLE = 3'b0, CMD = 3'd1, WAVE = 3'd2, HOLD = 3'd3;
|
||||
wire [2 : 0] state_c;
|
||||
wire wave_cnt_add, wave_cnt_end;
|
||||
wire [4 : 0] wave_cnt_c;
|
||||
wire hold_cnt_add, hold_cnt_end;
|
||||
wire [30 : 0] hold_cnt_c;
|
||||
|
||||
//wire cmd_fifo_has_empty = cmd_fifo_empty && cmd_fifo_rd_en;
|
||||
// ------------------------------------------------------
|
||||
// -- state machine
|
||||
// ------------------------------------------------------
|
||||
//jump conditions
|
||||
wire ilde2cmd = (state_c == IDLE) && start;
|
||||
wire cmd2wave = (state_c == CMD ) && ~cmd_fifo_data[31];
|
||||
wire cmd2hold = (state_c == CMD ) && cmd_fifo_data[31];
|
||||
wire wave2hold = (state_c == WAVE) && wave_cnt_end && cmd_fifo_data[31] && ~cmd_fifo_empty;
|
||||
wire wave2idle = (state_c == WAVE) && wave_cnt_end && cmd_fifo_empty;
|
||||
wire hold2wave = (state_c == HOLD) && hold_cnt_end && ~cmd_fifo_data[31] && ~cmd_fifo_empty;
|
||||
wire hold2idle = (state_c == HOLD) && hold_cnt_end && cmd_fifo_empty;
|
||||
//state_n
|
||||
wire [2 : 0] state_n = ((state_c == IDLE) && ilde2cmd ) ? CMD :
|
||||
((state_c == CMD ) && cmd2wave ) ? WAVE :
|
||||
((state_c == CMD ) && cmd2hold ) ? HOLD :
|
||||
((state_c == WAVE) && wave2hold ) ? HOLD :
|
||||
((state_c == WAVE) && wave2idle ) ? IDLE :
|
||||
((state_c == HOLD) && hold2wave ) ? WAVE :
|
||||
((state_c == HOLD) && hold2idle ) ? IDLE :
|
||||
state_c ;
|
||||
//state_c
|
||||
sirv_gnrl_dffr #(3) state_c_dffr (state_n, state_c, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- command decode
|
||||
// ------------------------------------------------------
|
||||
assign cmd_fifo_rd_en = ((state_c == CMD) || wave_cnt_end || hold_cnt_end) && ~cmd_fifo_empty;
|
||||
wire [4 : 0] cycle_num;
|
||||
wire [12 : 0] base_addr;
|
||||
wire [12 : 0] wave_leng;
|
||||
wire [30 : 0] hold_leng;
|
||||
sirv_gnrl_dfflr #( 5) cycle_num_dfflr (cmd_fifo_rd_en && ~cmd_fifo_data[31], cmd_fifo_data[30:26], cycle_num, clk, rst_n);
|
||||
sirv_gnrl_dfflr #(13) base_addr_dfflr (cmd_fifo_rd_en && ~cmd_fifo_data[31], cmd_fifo_data[25:13], base_addr, clk, rst_n);
|
||||
sirv_gnrl_dfflr #(13) wave_leng_dfflr (cmd_fifo_rd_en && ~cmd_fifo_data[31], cmd_fifo_data[12: 0], wave_leng, clk, rst_n);
|
||||
sirv_gnrl_dfflr #(31) hold_leng_dfflr (cmd_fifo_rd_en && cmd_fifo_data[31], cmd_fifo_data[30: 0], hold_leng, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- wave memory address count
|
||||
// ------------------------------------------------------
|
||||
wire [12 : 0] addr_cnt_c;
|
||||
wire addr_cnt_add = (state_c == WAVE);
|
||||
wire addr_cnt_end = addr_cnt_add && (addr_cnt_c == wave_leng - 1);
|
||||
wire [12 : 0] addr_cnt_n = addr_cnt_end ? 13'h0 :
|
||||
addr_cnt_add ? addr_cnt_c + 1'b1 :
|
||||
addr_cnt_c ;
|
||||
sirv_gnrl_dffr #(13) addr_cnt_c_dffr (addr_cnt_n, addr_cnt_c, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- wave repeat count
|
||||
// ------------------------------------------------------
|
||||
assign wave_cnt_add = addr_cnt_end;
|
||||
assign wave_cnt_end = wave_cnt_add && (wave_cnt_c == cycle_num - 1) && (cycle_num != 5'd0);
|
||||
wire [4 : 0] wave_cnt_n = wave_cnt_end ? 5'h0 :
|
||||
wave_cnt_add ? wave_cnt_c + 1'b1 :
|
||||
wave_cnt_c ;
|
||||
sirv_gnrl_dffr #( 5) wave_cnt_c_dffr (wave_cnt_n, wave_cnt_c, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- hold length count
|
||||
// ------------------------------------------------------
|
||||
assign hold_cnt_add = (state_c == HOLD);
|
||||
assign hold_cnt_end = hold_cnt_add && (hold_cnt_c == hold_leng - 1);
|
||||
wire [30 : 0] hold_cnt_n = hold_cnt_end ? 5'h0 :
|
||||
hold_cnt_add ? hold_cnt_c + 1'b1 :
|
||||
hold_cnt_c ;
|
||||
sirv_gnrl_dffr #(31) hold_cnt_c_dffr (hold_cnt_n, hold_cnt_c, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- read wave SRAM
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dffr #(1) sram_rd_en_dffr ((state_c == WAVE), sram_rd_en, clk, rst_n);
|
||||
sirv_gnrl_dffr #(13) sram_rd_addr_dffr (base_addr + addr_cnt_c, sram_rd_addr, clk, rst_n);
|
||||
|
||||
wire last_sram_rd_en, last_wave_data_vld;
|
||||
wire [7 : 0] last_rddata;
|
||||
sirv_gnrl_dffr #(1) last_sram_rd_en_dffr (wave_cnt_end, last_sram_rd_en, clk, rst_n);
|
||||
sirv_gnrl_dffr #(1) last_wave_data_dffr (last_sram_rd_en, last_wave_data_vld, clk, rst_n);
|
||||
sirv_gnrl_dfflr #(8) last_rddata_dfflr (last_wave_data_vld, sram_rd_data[511:504], last_rddata, clk, rst_n);
|
||||
|
||||
wire wave_vld, hold_vld_n, hold_vld;
|
||||
sirv_gnrl_dffr #(1) wave_vld_dffr (sram_rd_en, wave_vld, clk, rst_n);
|
||||
sirv_gnrl_dffr #(1) hold_vld_n_dffr ((state_c == HOLD), hold_vld_n, clk, rst_n);
|
||||
sirv_gnrl_dffr #(1) hold_vld_dffr (hold_vld_n, hold_vld, clk, rst_n);
|
||||
|
||||
wire [511: 0] wave_data = wave_vld ? sram_rd_data :
|
||||
hold_vld ? {64{last_rddata}} :
|
||||
512'd0 ;
|
||||
|
||||
sirv_gnrl_dffr #(1) wave_valid_dffr (wave_vld | hold_vld, wave_valid_out, clk, rst_n);
|
||||
sirv_gnrl_dfflr #(512) wave_data_dfflr (wave_vld | hold_vld | wave_valid_out, wave_data, wave_data_out, clk, rst_n);
|
||||
|
||||
//status
|
||||
assign status = state_c;
|
||||
assign wave_busy = (state_c == WAVE) || (state_c == HOLD);
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
//+FHDR--------------------------------------------------------------------------------------------------------
|
||||
// Company:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// File Name : awg_top.v
|
||||
// Department :
|
||||
// Author : hdzhang
|
||||
// Author's Tel :
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Relese History
|
||||
// Version Date Author Description
|
||||
// 0.1 2026-03-01 hdzhang awg-top
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Keywords :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Parameter
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Target Device:
|
||||
// Tool versions:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Reuse Issues
|
||||
// Reset Strategy:
|
||||
// Clock Domains:
|
||||
// Critical Timing:
|
||||
// Asynchronous I/F:
|
||||
// Synthesizable (y/n):
|
||||
// Other:
|
||||
//-FHDR--------------------------------------------------------------------------------------------------------
|
||||
|
||||
module awg_top (
|
||||
//system port
|
||||
input clk // System Main Clock
|
||||
,input rst_n // Spi Reset active low
|
||||
,input start
|
||||
//----------------------------from spi-----------------------------------------------------------
|
||||
//Wave storage read/write signal
|
||||
//A-port
|
||||
,input [511:0] wave_awrdata
|
||||
,input [0 :0] wave_awren
|
||||
,input [12 :0] wave_arwaddr
|
||||
,input [63 :0] wave_awrmask
|
||||
|
||||
//B-port
|
||||
,input [31 :0] wave_bwrdata
|
||||
,input [0 :0] wave_bwren
|
||||
,input [18 :0] wave_brwaddr
|
||||
,input [0 :0] wave_brden
|
||||
,output [31 :0] wave_brddata
|
||||
//cmd fifo read-write signal
|
||||
,input [31 :0] cmd_fifo_bwrdata
|
||||
,input [0 :0] cmd_fifo_bwren
|
||||
,input [7 :0] cmd_fifo_brwaddr
|
||||
,input [0 :0] cmd_fifo_brden
|
||||
,output [31 :0] cmd_fifo_brddata
|
||||
//----------------------------to system regfile------------------------------------------------------
|
||||
//CMD FIFO Empty & Full
|
||||
,output cmd_fifo_empty
|
||||
,output cmd_fifo_full
|
||||
//AWG Ctrl Status
|
||||
,output [2 :0] status
|
||||
,output wave_busy
|
||||
//----------------------------to DEM----------------------------------------------------------------
|
||||
,output [511:0] wave_data_out
|
||||
,output wave_valid_out
|
||||
);
|
||||
|
||||
wire start_r;
|
||||
sirv_gnrl_dffr #(1) start_dffr (start, start_r, clk, rst_n);
|
||||
|
||||
wire start_posedge = start && ~start_r;
|
||||
wire sync_start;
|
||||
sirv_gnrl_dffr #(1) sync_start_dffr (start_posedge, sync_start, clk, rst_n);
|
||||
|
||||
wire cmd_fifo_rd_en ;
|
||||
wire [31 :0] cmd_fifo_data ;
|
||||
//wire cmd_fifo_empty ;
|
||||
wire sram_rd_en ;
|
||||
wire [12 :0] sram_rd_addr ;
|
||||
wire [511:0] sram_rd_data ;
|
||||
|
||||
awg_ctrl awg_ctrl_inst(
|
||||
.clk ( clk )
|
||||
,.rst_n ( rst_n )
|
||||
,.start ( sync_start )
|
||||
,.cmd_fifo_rd_en ( cmd_fifo_rd_en )
|
||||
,.cmd_fifo_data ( cmd_fifo_data )
|
||||
,.cmd_fifo_empty ( cmd_fifo_empty )
|
||||
,.sram_rd_en ( sram_rd_en )
|
||||
,.sram_rd_addr ( sram_rd_addr )
|
||||
,.sram_rd_data ( sram_rd_data )
|
||||
,.wave_data_out ( wave_data_out )
|
||||
,.wave_valid_out ( wave_valid_out )
|
||||
,.status ( status )
|
||||
,.wave_busy ( wave_busy )
|
||||
);
|
||||
|
||||
//wire cmd_fifo_full ;
|
||||
wire cmd_fifo_almost_full ;
|
||||
wire cmd_fifo_almost_empty;
|
||||
wire cmd_fifo_prog_full ;
|
||||
wire cmd_fifo_prog_empty ;
|
||||
wire [5 :0] cmd_fifo_cnt ;
|
||||
|
||||
syn_fwft_fifo #(.width(32), .depth(64), .prog_full_thre(32), .prog_empty_thre(16))
|
||||
cmd_fifo_inst(
|
||||
.clk ( clk )
|
||||
,.rst ( ~rst_n )
|
||||
,.clr ( 1'b0 )
|
||||
,.wr_en ( cmd_fifo_bwren )
|
||||
,.rd_en ( cmd_fifo_rd_en )
|
||||
,.din ( cmd_fifo_bwrdata )
|
||||
,.dout ( cmd_fifo_data )
|
||||
,.full ( cmd_fifo_full )
|
||||
,.empty ( cmd_fifo_empty )
|
||||
,.almost_full ( cmd_fifo_almost_full )
|
||||
,.almost_empty ( cmd_fifo_almost_empty )
|
||||
,.prog_full ( cmd_fifo_prog_full )
|
||||
,.prog_empty ( cmd_fifo_prog_empty )
|
||||
,.cnt ( cmd_fifo_cnt )
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// wave sram
|
||||
//------------------------------------------------------------------------------------------
|
||||
sram_if #(19, 32) wave_sram_muxin (clk);
|
||||
sram_if #(19,512) wave_sram_muxout(clk);
|
||||
assign wave_sram_muxin.addr = wave_brwaddr[18:0] ;
|
||||
assign wave_sram_muxin.din = wave_bwrdata ;
|
||||
assign wave_sram_muxin.wben = 4'b1111 ;
|
||||
assign wave_sram_muxin.wren = wave_bwren ;
|
||||
assign wave_sram_muxin.rden = wave_brden ;
|
||||
assign wave_brddata = wave_sram_muxin.dout ;
|
||||
sram_dmux_w #(.ADDR_WIDTH(19), .DATA_WIDTH_I(32), .DATA_WIDTH_O(512))
|
||||
U_sram_dmux_w(
|
||||
.clk ( clk )
|
||||
,.rst_n ( rst_n )
|
||||
,.port_in ( wave_sram_muxin )
|
||||
,.port_out ( wave_sram_muxout )
|
||||
);
|
||||
//Wave Memory Clock
|
||||
|
||||
wire [0 :0] Wave_PortClk = clk ;
|
||||
//The wave storage A port is connected to the internal AWG controller
|
||||
wire [18 :0] Wave_PortAAddr = wave_awren ? {wave_arwaddr[12:0],6'b0} : {sram_rd_addr[12:0],6'b0};
|
||||
wire [511 :0] Wave_PortADataIn = wave_awrdata ;
|
||||
wire [0 :0] Wave_PortAWriteEnable = ~wave_awren ;
|
||||
wire [0 :0] Wave_PortAChipEnable = ~wave_awren&~sram_rd_en ;
|
||||
wire [512/8-1:0] Wave_PortAByteWriteEnable = ~wave_awrmask ;
|
||||
wire [511 :0] Wave_PortADataOut ;
|
||||
assign sram_rd_data = Wave_PortADataOut ;
|
||||
//The B port of the wave storage connects to an external SPI bus decode
|
||||
wire [18 :0] Wave_PortBAddr = wave_sram_muxout.addr[18:0] ;
|
||||
wire [511 :0] Wave_PortBDataIn = wave_sram_muxout.din ;
|
||||
wire [0 :0] Wave_PortBWriteEnable = ~wave_sram_muxout.wren & wave_sram_muxout.rden ;
|
||||
wire [0 :0] Wave_PortBChipEnable = ~(wave_sram_muxout.wren | wave_sram_muxout.rden) ;
|
||||
wire [512/8-1:0] Wave_PortBByteWriteEnable = ~wave_sram_muxout.wben ;
|
||||
wire [511 :0] Wave_PortBDataOut ;
|
||||
assign wave_sram_muxout.dout = Wave_PortBDataOut ;
|
||||
|
||||
dpram #(.DATAWIDTH(512), .ADDRWIDTH(19)) wave_dpram(
|
||||
.PortClk ( Wave_PortClk )
|
||||
,.PortAAddr ( Wave_PortAAddr )
|
||||
,.PortADataIn ( Wave_PortADataIn )
|
||||
,.PortAWriteEnable ( Wave_PortAWriteEnable )
|
||||
,.PortAChipEnable ( Wave_PortAChipEnable )
|
||||
,.PortAByteWriteEnable ( Wave_PortAByteWriteEnable )
|
||||
,.PortADataOut ( Wave_PortADataOut )
|
||||
,.PortBAddr ( Wave_PortBAddr )
|
||||
,.PortBDataIn ( Wave_PortBDataIn )
|
||||
,.PortBWriteEnable ( Wave_PortBWriteEnable )
|
||||
,.PortBChipEnable ( Wave_PortBChipEnable )
|
||||
,.PortBByteWriteEnable ( Wave_PortBByteWriteEnable )
|
||||
,.PortBDataOut ( Wave_PortBDataOut )
|
||||
);
|
||||
endmodule
|
||||
|
||||
|
|
@ -0,0 +1,599 @@
|
|||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2026/02/28 19:57:30
|
||||
// Design Name:
|
||||
// Module Name: dac_regfile
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
// Revision Date: 2026/02/28 19:57:30
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// -- Register address offset macros
|
||||
// -----------------------------------------------------------
|
||||
//Prbs_en Ctrl Register
|
||||
|
||||
`define CCALRSTNR 8'h00
|
||||
`define CCLKDCCENR 8'h04
|
||||
`define CASCLKCTR 8'h08
|
||||
`define CCALDCCQECPIR 8'h0C
|
||||
`define CCALQECCTR1 8'h10
|
||||
`define CCALDCCCTR1 8'h14
|
||||
`define CCALPICTR 8'h18
|
||||
`define CCALCROSSCTR 8'h1C
|
||||
`define CCALRSVR0 8'h20
|
||||
`define CCALRSVR1 8'h24
|
||||
`define SELCK10GDR 8'h28
|
||||
`define SELCK2P5GDR 8'h2C
|
||||
`define SELCK625MDR 8'h30
|
||||
`define P2SDATAENR 8'h34
|
||||
`define ENALLPR 8'h38
|
||||
`define ENPIPR 8'h3C
|
||||
`define CLKDIVRSTNR 8'h40
|
||||
`define P2SRSVR0 8'h44
|
||||
`define P2SRSVR1 8'h48
|
||||
`define CKRXSWR 8'h4C
|
||||
`define RSTCKR 8'h50
|
||||
`define CTRLZINR 8'h54
|
||||
|
||||
|
||||
module clk_regfile (
|
||||
//system port
|
||||
input clk // System Main Clock
|
||||
,input rstn // Spi Reset active low
|
||||
//rw op port
|
||||
,input [31 :0] wrdata // write data
|
||||
,input wren // write enable
|
||||
,input [7 :0] rwaddr // read & write address
|
||||
,input rden // read enable
|
||||
,output [31 :0] rddata // read data
|
||||
,output [0 :0] CcalRstn
|
||||
,output [3 :0] EnAllP
|
||||
,output [0 :0] DccEn
|
||||
,output [0 :0] CasGateCkCtrl
|
||||
,output [0 :0] SpiEnPi
|
||||
,output [0 :0] SpiEnQec
|
||||
,output [0 :0] SpiEnDcc
|
||||
,output [4 :0] SpiQecCtrlIp
|
||||
,output [4 :0] SpiQecCtrlIn
|
||||
,output [4 :0] SpiQecCtrlQp
|
||||
,output [4 :0] SpiQecCtrlQn
|
||||
,output [5 :0] SpiDccCtrlIup
|
||||
,output [5 :0] SpiDccCtrlIdn
|
||||
,output [5 :0] SpiDccCtrlQup
|
||||
,output [5 :0] SpiDccCtrlQdn
|
||||
,output [7 :0] SpiSiqNOut
|
||||
,output [7 :0] SpiSiqPOut
|
||||
,output [3 :0] SpiSiPOut
|
||||
,output [3 :0] SpiSqPOut
|
||||
,output [2 :0] CrtlCrossOverN
|
||||
,output [2 :0] CrtlCrossOverP
|
||||
,output [31 :0] CcalRsv0
|
||||
,output [31 :0] CcalRsv1
|
||||
,output [3 :0] SelCk10GDig
|
||||
,output [3 :0] SelCk2p5GDig
|
||||
,output [8 :0] SelCk625MDig
|
||||
,output [15 :0] P2sDataEn
|
||||
,output [15 :0] P2sEnAllP
|
||||
,output [15 :0] EnPiP
|
||||
,output [15 :0] CkDivRstn
|
||||
,output [31 :0] p2srsv0
|
||||
,output [31 :0] p2srsv1
|
||||
,output [15 :0] CkRxSw
|
||||
,output [15 :0] RstnCk
|
||||
,output [15 :0] CtrlZin
|
||||
);
|
||||
|
||||
localparam L = 1'b0,
|
||||
H = 1'b1;
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Register Default Vaule
|
||||
// ------------------------------------------------------
|
||||
wire [0 :0] ccalrstnrdft = 1'b0 ; // CCALRSTNR 16'h0000
|
||||
wire [4 :0] cclkdccenrdft = 5'b0 ; // CCLKDCCENR 16'h0004
|
||||
wire [0 :0] casclkctrdft = 1'b1 ; // CASCLKCTR 16'h0008
|
||||
wire [2 :0] ccaldccqecpirdft = 3'b0 ; // CCALDCCQECPIR 16'h000C
|
||||
wire [19:0] ccalqecctr1dft = {5'b10001,5'b10001,5'b10000,5'b10000} ; // CCALQECCTR1 16'h0010
|
||||
wire [23:0] ccaldccctr1dft = {6'b111111,6'b000000,6'b111111,6'b000000} ; // CCALDCCCTR1 16'h0014
|
||||
wire [23:0] ccalpictrdft = {8'b11111111,8'b00000000,4'b0011,4'b0000} ; // CCALPICTR 16'h0018
|
||||
wire [5 :0] ccalcrossctrdft = {3'b100,3'b110} ; // CCALCROSSCTR 16'h001C
|
||||
wire [31:0] ccalrsvr0dft = 32'h0 ; // CCALRSVR0 16'h0020
|
||||
wire [31:0] ccalrsvr1dft = 32'h0 ; // CCALRSVR1 16'h0024
|
||||
wire [3 :0] selck10gdrdft = 4'b0001 ; // SELCK10GDR 16'h0028
|
||||
wire [3 :0] selck2p5gdrdft = 4'b0010 ; // SELCK2P5GDR 16'h002C
|
||||
wire [8 :0] selck625mdrdft = 9'b100001010 ; // SELCK625MDR 16'h0030
|
||||
wire [15:0] p2sdataenrdft = 16'h1 ; // P2SDATAENR 16'h0034
|
||||
wire [15:0] enallprdft = 16'h1 ; // ENALLPR 16'h0038
|
||||
wire [15:0] enpiprdft = 16'h1 ; // ENPIPR 16'h003C
|
||||
wire [15:0] clkdivrstnrdft = 16'h1 ; // CLKDIVRSTNR 16'h0040
|
||||
wire [31:0] p2srsvr0dft = 32'h0 ; // P2SRSVR0 16'h0044
|
||||
wire [31:0] p2srsvr1dft = 32'h0 ; // P2SRSVR1 16'h0048
|
||||
wire [15:0] ckrxswrdft = 16'h1 ; // CKRXSWR 16'h004C
|
||||
wire [15:0] rstckrdft = 16'h1 ; // RSTCKR 16'h0050
|
||||
wire [15:0] ctrzinrdft = 16'h1 ; // CTRLZINR 16'h0054
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Register enable (select) wires
|
||||
// ------------------------------------------------------
|
||||
wire ccalrstnren ; // CCALRSTNR Enable
|
||||
wire cclkdccenren ; // CCLKDCCEN Enable
|
||||
wire casclkctren ; // CASCLKCTR Enable
|
||||
wire ccaldccqecpiren ; // CCALDCCQECPIR Enable
|
||||
wire ccalqecctr1en ; // CCALQECCTR1 Enable
|
||||
wire ccaldccctr1en ; // CCALDCCCTR1 Enable
|
||||
wire ccalpictren ; // CCALPICTR Enable
|
||||
wire ccalcrossctren ; // CCALCROSSCTR Enable
|
||||
wire ccalrsvr0en ; // CCALRSVR0 Enable
|
||||
wire ccalrsvr1en ; // CCALRSVR1 Enable
|
||||
wire selck10gdren ; // SELCK10GDR Enable
|
||||
wire selck2p5gdren ; // SELCK2P5GDR Enable
|
||||
wire selck625mdren ; // SELCK625MDR Enable
|
||||
wire p2sdataenren ; // P2SDATAENR Enable
|
||||
wire enallpren ; // ENALLPR Enable
|
||||
wire enpipren ; // ENPIPR Enable
|
||||
wire clkdivrstnren ; // CLKDIVRSTNR Enable
|
||||
wire p2srsvr0en ; // P2SRSVR0 Enable
|
||||
wire p2srsvr1en ; // P2SRSVR1 Enable
|
||||
wire ckrxswren ; // CKRXSWR Enable
|
||||
wire rstckren ; // RSTCKR Enable
|
||||
wire ctrzinren ; // CTRLZINR Enable
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Register write enable wires
|
||||
// ------------------------------------------------------
|
||||
wire ccalrstnrwe ; // CCALRSTNR Write Enable
|
||||
wire cclkdccenrwe ; // CCLKDCCEN Write Enable
|
||||
wire casclkctrwe ; // CASCLKCTR Write Enable
|
||||
wire ccaldccqecpirwe ; // CCALDCCQECPIR Write Enable
|
||||
wire ccalqecctr1we ; // CCALQECCTR1 Write Enable
|
||||
wire ccaldccctr1we ; // CCALDCCCTR1 Write Enable
|
||||
wire ccalpictrwe ; // CCALPICTR Write Enable
|
||||
wire ccalcrossctrwe ; // CCALCROSSCTR Write Enable
|
||||
wire ccalrsvr0we ; // CCALRSVR0 Write Enable
|
||||
wire ccalrsvr1we ; // CCALRSVR1 Write Enable
|
||||
wire selck10gdrwe ; // SELCK10GDR Write Enable
|
||||
wire selck2p5gdrwe ; // SELCK2P5GDR Write Enable
|
||||
wire selck625mdrwe ; // SELCK625MDR Write Enable
|
||||
wire p2sdataenrwe ; // P2SDATAENR Write Enable
|
||||
wire enallprwe ; // ENALLPR Write Enable
|
||||
wire enpiprwe ; // ENPIPR Write Enable
|
||||
wire clkdivrstnrwe ; // CLKDIVRSTNR Write Enable
|
||||
wire p2srsvr0we ; // P2SRSVR0 Write Enable
|
||||
wire p2srsvr1we ; // P2SRSVR1 Write Enable
|
||||
wire ckrxswrwe ; // CKRXSWR Write Enable
|
||||
wire rstckrwe ; // RSTCKR Write Enable
|
||||
wire ctrzinrwe ; // CTRLZINR Write Enable
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Misc Registers
|
||||
// ------------------------------------------------------
|
||||
wire [0 :0] ccalrstnr ; // CCALRSTNR Register, Default vaule is 1'b0
|
||||
wire [4 :0] cclkdccenr ; // CCLKDCCEN Register, Default vaule is 5'b0
|
||||
wire [0 :0] casclkctr ; // CASCLKCTR Register, Default vaule is 1'b1
|
||||
wire [2 :0] ccaldccqecpir ; // CCALDCCQECPIR Register, Default vaule is 3'b0
|
||||
wire [19:0] ccalqecctr1 ; // CCALQECCTR1 Register, Default vaule is {5'b10001,5'b10001,5'b10000,5'b10000}
|
||||
wire [23:0] ccaldccctr1 ; // CCALDCCCTR1 Register, Default vaule is {6'b111111,6'b000000,6'b111111,6'b000000}
|
||||
wire [23:0] ccalpictr ; // CCALPICTR Register, Default vaule is {8'b11111111,8'b00000000,4'b0011,4'b0011}
|
||||
wire [5 :0] ccalcrossctr ; // CCALCROSSCTR Register, Default vaule is {3'b100,3'b110}
|
||||
wire [31:0] ccalrsvr0 ; // CCALRSVR0 Register, Default vaule is 32'h0
|
||||
wire [31:0] ccalrsvr1 ; // CCALRSVR1 Register, Default vaule is 32'h0
|
||||
wire [3 :0] selck10gdr ; // SELCK10GDR Register, Default vaule is 4'b0001
|
||||
wire [3 :0] selck2p5gdr ; // SELCK2P5GDR Register, Default vaule is 4'b0010
|
||||
wire [8 :0] selck625mdr ; // SELCK625MDR Register, Default vaule is 9'b100001010
|
||||
wire [15:0] p2sdataenr ; // P2SDATAENR Register, Default vaule is 16'h1
|
||||
wire [15:0] enallpr ; // ENALLPR Register, Default vaule is 16'h1
|
||||
wire [15:0] enpipr ; // ENPIPR Register, Default vaule is 16'h1
|
||||
wire [15:0] clkdivrstnr ; // CLKDIVRSTNR Register, Default vaule is 16'h1
|
||||
wire [31:0] p2srsvr0 ; // P2SRSVR0 Register, Default vaule is 32'h0
|
||||
wire [31:0] p2srsvr1 ; // P2SRSVR1 Register, Default vaule is 32'h0
|
||||
wire [15:0] ckrxswr ; // CKRXSWR Register, Default vaule is 16'h1
|
||||
wire [15:0] rstckr ; // RSTCKR Register, Default vaule is 16'h1
|
||||
wire [15:0] ctrzinr ; // CTRLZINR Register, Default vaule is 16'h1
|
||||
|
||||
reg [31 :0] rddata_reg ;
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Address decoder
|
||||
//
|
||||
// Decodes the register address offset input(reg_addr)
|
||||
// to produce enable (select) signals for each of the
|
||||
// SW-registers in the macrocell. The reg_addr input
|
||||
// is bits [15:0] of the paddr bus.
|
||||
// ------------------------------------------------------
|
||||
assign ccalrstnren = (rwaddr[7:2] == `CCALRSTNR >>2) ? 1'b1 : 1'b0; // CCALRSTNR Enable
|
||||
assign cclkdccenren = (rwaddr[7:2] == `CCLKDCCENR >>2) ? 1'b1 : 1'b0; // CCLKDCCEN Enable
|
||||
assign casclkctren = (rwaddr[7:2] == `CASCLKCTR >>2) ? 1'b1 : 1'b0; // CASCLKCTR Enable
|
||||
assign ccaldccqecpiren = (rwaddr[7:2] == `CCALDCCQECPIR >>2) ? 1'b1 : 1'b0; // CCALDCCQECPIR Enable
|
||||
assign ccalqecctr1en = (rwaddr[7:2] == `CCALQECCTR1 >>2) ? 1'b1 : 1'b0; // CCALQECCTR1 Enable
|
||||
assign ccaldccctr1en = (rwaddr[7:2] == `CCALDCCCTR1 >>2) ? 1'b1 : 1'b0; // CCALDCCCTR1 Enable
|
||||
assign ccalpictren = (rwaddr[7:2] == `CCALPICTR >>2) ? 1'b1 : 1'b0; // CCALPICTR Enable
|
||||
assign ccalcrossctren = (rwaddr[7:2] == `CCALCROSSCTR >>2) ? 1'b1 : 1'b0; // CCALCROSSCTR Enable
|
||||
assign ccalrsvr0en = (rwaddr[7:2] == `CCALRSVR0 >>2) ? 1'b1 : 1'b0; // CCALRSVR0 Enable
|
||||
assign ccalrsvr1en = (rwaddr[7:2] == `CCALRSVR1 >>2) ? 1'b1 : 1'b0; // CCALRSVR1 Enable
|
||||
assign selck10gdren = (rwaddr[7:2] == `SELCK10GDR >>2) ? 1'b1 : 1'b0; // SELCK10GDR Enable
|
||||
assign selck2p5gdren = (rwaddr[7:2] == `SELCK2P5GDR >>2) ? 1'b1 : 1'b0; // SELCK2P5GDR Enable
|
||||
assign selck625mdren = (rwaddr[7:2] == `SELCK625MDR >>2) ? 1'b1 : 1'b0; // SELCK625MDR Enable
|
||||
assign p2sdataenren = (rwaddr[7:2] == `P2SDATAENR >>2) ? 1'b1 : 1'b0; // P2SDATAENR Enable
|
||||
assign enallpren = (rwaddr[7:2] == `ENALLPR >>2) ? 1'b1 : 1'b0; // ENALLPR Enable
|
||||
assign enpipren = (rwaddr[7:2] == `ENPIPR >>2) ? 1'b1 : 1'b0; // ENPIPR Enable
|
||||
assign clkdivrstnren = (rwaddr[7:2] == `CLKDIVRSTNR >>2) ? 1'b1 : 1'b0; // CLKDIVRSTNR Enable
|
||||
assign p2srsvr0en = (rwaddr[7:2] == `P2SRSVR0 >>2) ? 1'b1 : 1'b0; // P2SRSVR0 Enable
|
||||
assign p2srsvr1en = (rwaddr[7:2] == `P2SRSVR1 >>2) ? 1'b1 : 1'b0; // P2SRSVR1 Enable
|
||||
assign ckrxswren = (rwaddr[7:2] == `CKRXSWR >>2) ? 1'b1 : 1'b0; // CKRXSWR Enable
|
||||
assign rstckren = (rwaddr[7:2] == `RSTCKR >>2) ? 1'b1 : 1'b0; // RSTCKR Enable
|
||||
assign ctrzinren = (rwaddr[7:2] == `CTRLZINR >>2) ? 1'b1 : 1'b0; // CTRLZINR Enable
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Write enable signals
|
||||
//
|
||||
// Write enable signals for writable SW-registers.
|
||||
// The write enable for each register is the ANDed
|
||||
// result of the register enable and the input reg_wren
|
||||
// ------------------------------------------------------
|
||||
assign ccalrstnrwe = ccalrstnren & wren; // CCALRSTNR Write Enable
|
||||
assign cclkdccenrwe = cclkdccenren & wren; // CCLKDCCEN Write Enable
|
||||
assign casclkctrwe = casclkctren & wren; // CASCLKCTR Write Enable
|
||||
assign ccaldccqecpirwe = ccaldccqecpiren & wren; // CCALDCCQECPIR Write Enable
|
||||
assign ccalqecctr1we = ccalqecctr1en & wren; // CCALQECCTR1 Write Enable
|
||||
assign ccaldccctr1we = ccaldccctr1en & wren; // CCALDCCCTR1 Write Enable
|
||||
assign ccalpictrwe = ccalpictren & wren; // CCALPICTR Write Enable
|
||||
assign ccalcrossctrwe = ccalcrossctren & wren; // CCALCROSSCTR Write Enable
|
||||
assign ccalrsvr0we = ccalrsvr0en & wren; // CCALRSVR0 Write Enable
|
||||
assign ccalrsvr1we = ccalrsvr1en & wren; // CCALRSVR1 Write Enable
|
||||
assign selck10gdrwe = selck10gdren & wren; // SELCK10GDR Write Enable
|
||||
assign selck2p5gdrwe = selck2p5gdren & wren; // SELCK2P5GDR Write Enable
|
||||
assign selck625mdrwe = selck625mdren & wren; // SELCK625MDR Write Enable
|
||||
assign p2sdataenrwe = p2sdataenren & wren; // P2SDATAENR Write Enable
|
||||
assign enallprwe = enallpren & wren; // ENALLPR Write Enable
|
||||
assign enpiprwe = enpipren & wren; // ENPIPR Write Enable
|
||||
assign clkdivrstnrwe = clkdivrstnren & wren; // CLKDIVRSTNR Write Enable
|
||||
assign p2srsvr0we = p2srsvr0en & wren; // P2SRSVR0 Write Enable
|
||||
assign p2srsvr1we = p2srsvr1en & wren; // P2SRSVR1 Write Enable
|
||||
assign ckrxswrwe = ckrxswren & wren; // CKRXSWR Write Enable
|
||||
assign rstckrwe = rstckren & wren; // RSTCKR Write Enable
|
||||
assign ctrzinrwe = ctrzinren & wren; // CTRLZINR Write Enable
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- ccalrstnr Register
|
||||
//
|
||||
// Write ccalrstnr for 'CCALRSTNR' : 1-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [0:0] --> ccalrstnr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(1) ccalrstnr_dfflrd (ccalrstnrdft, ccalrstnrwe, wrdata[0], ccalrstnr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- cclkdccenr Register
|
||||
//
|
||||
// Write cclkdccenr for 'CCLKDCCEN' : 5-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [4:0] --> cclkdccenr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(5) cclkdccenr_dfflrd (cclkdccenrdft, cclkdccenrwe, wrdata[4:0], cclkdccenr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- casclkctr Register
|
||||
//
|
||||
// Write casclkctr for 'CASCLKCTR' : 1-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [0:0] --> casclkctr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(1) casclkctr_dfflrd (casclkctrdft, casclkctrwe, wrdata[0], casclkctr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- ccaldccqecpir Register
|
||||
//
|
||||
// Write ccaldccqecpir for 'CCALDCCQECPIR' : 3-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [2:0] --> ccaldccqecpir
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(3) ccaldccqecpir_dfflrd (ccaldccqecpirdft, ccaldccqecpirwe, wrdata[2:0], ccaldccqecpir, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- ccalqecctr1 Register
|
||||
//
|
||||
// Write ccalqecctr1 for 'CCALQECCTR1' : 20-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [19:0] --> ccalqecctr1
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(20) ccalqecctr1_dfflrd (ccalqecctr1dft, ccalqecctr1we, wrdata[19:0], ccalqecctr1, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- ccaldccctr1 Register
|
||||
//
|
||||
// Write ccaldccctr1 for 'CCALDCCCTR1' : 24-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [23:0] --> ccaldccctr1
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(24) biasct3r_dfflrd (ccaldccctr1dft, ccaldccctr1we, wrdata[23:0], ccaldccctr1, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- ccalpictr Register
|
||||
//
|
||||
// Write ccalpictr for 'CCALPICTR' : 24-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [23:0] --> ccalpictr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(24) ccalpictr_dfflrd (ccalpictrdft, ccalpictrwe, wrdata[23:0], ccalpictr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- ccalcrossctr Register
|
||||
//
|
||||
// Write ccalcrossctr for 'CCALCROSSCTR' : 6-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [5:0] --> ccalcrossctr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(6) ccalcrossctr_dfflrd (ccalcrossctrdft, ccalcrossctrwe, wrdata[5:0], ccalcrossctr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- ccalrsvr0 Register
|
||||
//
|
||||
// Write ccalrsvr0 for 'CCALRSVR0' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> ccalrsvr0
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) ccalrsvr0_dfflrd (ccalrsvr0dft, ccalrsvr0we, wrdata[31:0], ccalrsvr0, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- ccalrsvr1 Register
|
||||
//
|
||||
// Write ccalrsvr1 for 'CCALRSVR1' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> ccalrsvr1
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) ccalrsvr1_dfflrd (ccalrsvr1dft, ccalrsvr1we, wrdata[31:0], ccalrsvr1, clk, rstn);
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- selck10gdr Register
|
||||
//
|
||||
// Write selck10gdr for 'SELCK10GDR' : 4-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [3:0] --> selck10gdr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(4) selck10gdr_dfflrd (selck10gdrdft, selck10gdrwe, wrdata[3:0], selck10gdr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- selck2p5gdr Register
|
||||
//
|
||||
// Write selck2p5gdr for 'SELCK2P5GDR' : 4-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [3:0] --> selck2p5gdr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(4) selck2p5gdr_dfflrd (selck2p5gdrdft, selck2p5gdrwe, wrdata[3:0], selck2p5gdr, clk, rstn);
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- selck625mdr Register
|
||||
//
|
||||
// Write selck625mdr for 'SELCK625MDR' : 9-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [8:0] --> selck625mdr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(9) selck625mdr_dfflrd (selck625mdrdft, selck625mdrwe, wrdata[8:0], selck625mdr, clk, rstn);
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- p2sdataenr Register
|
||||
//
|
||||
// Write p2sdataenr for 'P2SDATAENR' : 16-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [15:0] --> p2sdataenr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(16) p2sdataenr_dfflrd (p2sdataenrdft, p2sdataenrwe, wrdata[15:0], p2sdataenr, clk, rstn);
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- enallpr Register
|
||||
//
|
||||
// Write enallpr for 'ENALLPR' : 16-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [15:0] --> enallpr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(16) enallpr_dfflrd (enallprdft, enallprwe, wrdata[15:0], enallpr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- enpipr Register
|
||||
//
|
||||
// Write enpipr for 'ENPIPR' : 16-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [15:0] --> enpipr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(16) enpipr_dfflrd (enpiprdft, enpiprwe, wrdata[15:0], enpipr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- clkdivrstnr Register
|
||||
//
|
||||
// Write clkdivrstnr for 'CLKDIVRSTNR' : 16-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [15:0] --> clkdivrstnr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(16) clkdivrstnr_dfflrd (clkdivrstnrdft, clkdivrstnrwe, wrdata[15:0], clkdivrstnr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- p2srsvr0 Register
|
||||
//
|
||||
// Write p2srsvr0 for 'P2SRSVR0' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> p2srsvr0
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) p2srsvr0_dfflrd (p2srsvr0dft, p2srsvr0we, wrdata[31:0], p2srsvr0, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- p2srsvr1 Register
|
||||
//
|
||||
// Write p2srsvr1 for 'P2SRSVR1' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> p2srsvr1
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) p2srsvr1_dfflrd (p2srsvr1dft, p2srsvr1we, wrdata[31:0], p2srsvr1, clk, rstn);
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- ckrxswr Register
|
||||
//
|
||||
// Write ckrxswr for 'CKRXSWR' : 16-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [15:0] --> ckrxswr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(16) ckrxswr_dfflrd (ckrxswrdft, ckrxswrwe, wrdata[15:0], ckrxswr, clk, rstn);
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- rstckr Register
|
||||
//
|
||||
// Write rstckr for 'RSTCKR' : 16-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [15:0] --> rstckr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(16) rstckr_dfflrd (rstckrdft, rstckrwe, wrdata[15:0], rstckr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- ctrzinr Register
|
||||
//
|
||||
// Write ctrzinr for 'CTRLZINR' : 16-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [15:0] --> ctrzinr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(16) ctrzinr_dfflrd (ctrzinrdft, ctrzinrwe, wrdata[15:0], ctrzinr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Read data mux
|
||||
//
|
||||
// -- The data from the selected register is
|
||||
// -- placed on a zero-padded 32-bit read data bus.
|
||||
// ------------------------------------------------------
|
||||
always @(*) begin : RDDATA_PROC
|
||||
rddata_reg = {32{1'b0}};
|
||||
if(ccalrstnren == H ) rddata_reg[0 :0] = ccalrstnr[0 :0] ;
|
||||
if(cclkdccenren == H ) rddata_reg[4 :0] = cclkdccenr[4 :0] ;
|
||||
if(casclkctren == H ) rddata_reg[0 :0] = casclkctr[0 :0] ;
|
||||
if(ccaldccqecpiren == H ) rddata_reg[2 :0] = ccaldccqecpir[2 :0] ;
|
||||
if(ccalqecctr1en == H ) rddata_reg[19:0] = ccalqecctr1[19:0] ;
|
||||
if(ccaldccctr1en == H ) rddata_reg[23:0] = ccaldccctr1[23:0] ;
|
||||
if(ccalpictren == H ) rddata_reg[23:0] = ccalpictr[23:0] ;
|
||||
if(ccalcrossctren == H ) rddata_reg[5 :0] = ccalcrossctr[5 :0] ;
|
||||
if(ccalrsvr0en == H ) rddata_reg[31:0] = ccalrsvr0[31:0] ;
|
||||
if(ccalrsvr1en == H ) rddata_reg[31:0] = ccalrsvr1[31:0] ;
|
||||
if(selck10gdren == H ) rddata_reg[3 :0] = selck10gdr[3 :0] ;
|
||||
if(selck2p5gdren == H ) rddata_reg[3 :0] = selck2p5gdr[3 :0] ;
|
||||
if(selck625mdren == H ) rddata_reg[8 :0] = selck625mdr[8 :0] ;
|
||||
if(p2sdataenren == H ) rddata_reg[15:0] = p2sdataenr[15:0] ;
|
||||
if(enallpren == H ) rddata_reg[15:0] = enallpr[15:0] ;
|
||||
if(enpipren == H ) rddata_reg[15:0] = enpipr[15:0] ;
|
||||
if(clkdivrstnren == H ) rddata_reg[15:0] = clkdivrstnr[15:0] ;
|
||||
if(p2srsvr0en == H ) rddata_reg[31:0] = p2srsvr0[31:0] ;
|
||||
if(p2srsvr1en == H ) rddata_reg[31:0] = p2srsvr1[31:0] ;
|
||||
if(ckrxswren == H ) rddata_reg[15:0] = ckrxswr[15:0] ;
|
||||
if(rstckren == H ) rddata_reg[15:0] = rstckr[15:0] ;
|
||||
if(ctrzinren == H ) rddata_reg[15:0] = ctrzinr[15:0] ;
|
||||
end
|
||||
|
||||
//rddata
|
||||
sirv_gnrl_dffr #(32) rddata_dffr (rddata_reg, rddata, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Output signals assignment
|
||||
// ------------------------------------------------------
|
||||
assign CcalRstn = ccalrstnr ;
|
||||
assign EnAllP = cclkdccenr ;
|
||||
assign DccEn = casclkctr ;
|
||||
assign CasGateCkCtrl = casclkctr ;
|
||||
assign SpiEnPi = ccaldccqecpir[2] ;
|
||||
assign SpiEnQec = ccaldccqecpir[1] ;
|
||||
assign SpiEnDcc = ccaldccqecpir[0] ;
|
||||
assign SpiQecCtrlIp = ccalqecctr1[19:15] ;
|
||||
assign SpiQecCtrlIn = ccalqecctr1[14:10] ;
|
||||
assign SpiQecCtrlQp = ccalqecctr1[9 : 5] ;
|
||||
assign SpiQecCtrlQn = ccalqecctr1[4 : 0] ;
|
||||
|
||||
assign SpiDccCtrlIup = ccaldccctr1[23:18] ;
|
||||
assign SpiDccCtrlIdn = ccaldccctr1[17:12] ;
|
||||
assign SpiDccCtrlQup = ccaldccctr1[11: 6] ;
|
||||
assign SpiDccCtrlQdn = ccaldccctr1[5 : 0] ;
|
||||
|
||||
assign SpiSiqNOut = ccalpictr[23:16] ;
|
||||
assign SpiSiqPOut = ccalpictr[15: 8] ;
|
||||
assign SpiSiPOut = ccalpictr[7 : 4] ;
|
||||
assign SpiSqPOut = ccalpictr[3 : 0] ;
|
||||
|
||||
assign CrtlCrossOverN = ccalcrossctr[5:3] ;
|
||||
assign CrtlCrossOverP = ccalcrossctr[2:0] ;
|
||||
assign CcalRsv0 = ccalrsvr0 ;
|
||||
assign CcalRsv1 = ccalrsvr0 ;
|
||||
|
||||
assign SelCk10GDig = selck10gdr ;
|
||||
assign SelCk2p5GDig = selck2p5gdr ;
|
||||
assign SelCk625MDig = selck625mdr ;
|
||||
assign P2sDataEn = p2sdataenr ;
|
||||
assign P2sEnAllP = enallpr ;
|
||||
assign EnPiP = enpipr ;
|
||||
assign CkDivRstn = clkdivrstnr ;
|
||||
assign p2srsv0 = p2srsvr0 ;
|
||||
assign p2srsv1 = p2srsvr1 ;
|
||||
assign CkRxSw = ckrxswr ;
|
||||
assign RstnCk = rstckr ;
|
||||
assign CtrlZin = ctrzinr ;
|
||||
|
||||
endmodule
|
||||
|
||||
`undef CCALRSTNR
|
||||
`undef CCLKDCCENR
|
||||
`undef CASCLKCTR
|
||||
`undef CCALDCCQECPIR
|
||||
`undef CCALQECCTR1
|
||||
`undef CCALDCCCTR1
|
||||
`undef CCALPICTR
|
||||
`undef CCALCROSSCTR
|
||||
`undef CCALRSVR0
|
||||
`undef CCALRSVR1
|
||||
`undef SELCK10GDR
|
||||
`undef SELCK2P5GDR
|
||||
`undef SELCK625MDR
|
||||
`undef P2SDATAENR
|
||||
`undef ENALLPR
|
||||
`undef ENPIPR
|
||||
`undef CLKDIVRSTNR
|
||||
`undef P2SRSVR0
|
||||
`undef P2SRSVR1
|
||||
`undef CKRXSWR
|
||||
`undef RSTCKR
|
||||
`undef CTRLZINR
|
||||
`undef VERSIONR
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
|
||||
module pulse_generator #(
|
||||
parameter DATA_WIDTH = 16
|
||||
)(
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
input logic pulse_en,
|
||||
input logic [DATA_WIDTH-1:0] delay,
|
||||
input logic [DATA_WIDTH-1:0] width,
|
||||
input logic inv_en,
|
||||
output logic pulse
|
||||
);
|
||||
|
||||
logic [DATA_WIDTH-1:0] counter; // 用于延迟和宽度计数
|
||||
|
||||
logic pulse_delay_done;
|
||||
logic pulse_width_done;
|
||||
assign pulse_delay_done = (counter == delay);
|
||||
assign pulse_width_done = (counter == width);
|
||||
|
||||
localparam SM_IDLE = 0;
|
||||
localparam SM_WAIT = 1;
|
||||
localparam SM_WORK = 2;
|
||||
logic [1:0] current_state;
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
current_state <= SM_IDLE;
|
||||
end else begin
|
||||
case(current_state)
|
||||
SM_IDLE: current_state <= pulse_en ? SM_WAIT : SM_IDLE;
|
||||
SM_WAIT: current_state <= pulse_delay_done ? SM_WORK : SM_WAIT;
|
||||
SM_WORK: current_state <= pulse_width_done ? SM_IDLE : SM_WORK;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
case(current_state)
|
||||
SM_IDLE: counter <= 1;
|
||||
SM_WAIT: counter <= pulse_delay_done ? 1 : (counter + 1);
|
||||
SM_WORK: counter <= pulse_width_done ? 1 : (counter + 1);
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
always @(posedge clk) begin
|
||||
case(current_state)
|
||||
SM_IDLE: pulse <= inv_en;
|
||||
SM_WAIT: pulse <= pulse_delay_done ? ~inv_en : inv_en;
|
||||
SM_WORK: pulse <= pulse_width_done ? inv_en : ~inv_en;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
module ramp_gen (
|
||||
// system ports
|
||||
input clk,
|
||||
input rst_n,
|
||||
input [1:0] dac_mode_sel,
|
||||
input cen,
|
||||
input [7:0] step, // 8-bit step value
|
||||
input fixed,
|
||||
input [7:0] fixed_value, // 8-bit fixed value
|
||||
input [31:0] ifs,
|
||||
output [7:0] ramp [63:0], // 64 channels of 8-bit output
|
||||
output ramp_vld
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Counter to generate ramp_add_en enable signal
|
||||
//////////////////////////////////////////////////////////////
|
||||
reg [31:0] cnt_c;
|
||||
wire add_cnt = cen & ~fixed;
|
||||
wire end_cnt = add_cnt && (cnt_c == ifs - 1);
|
||||
|
||||
wire [31:0] cnt_n = end_cnt ? 32'h0 :
|
||||
add_cnt ? cnt_c + 1'b1 :
|
||||
cnt_c;
|
||||
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) cnt_c <= 32'h0;
|
||||
else cnt_c <= cnt_n;
|
||||
end
|
||||
|
||||
reg ramp_add_en;
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) ramp_add_en <= 1'b0;
|
||||
else ramp_add_en <= end_cnt | ((ifs == 32'b0) & cen) | fixed;
|
||||
end
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Pre-calculated step multiples (for special mode)
|
||||
//////////////////////////////////////////////////////////////
|
||||
wire [7:0] step2_w = step << 1;
|
||||
wire [7:0] step4_w = step << 2;
|
||||
wire [7:0] step8_w = step << 3;
|
||||
wire [7:0] step16_w = step << 4;
|
||||
wire [7:0] step32_w = step << 5;
|
||||
wire [7:0] step64_w = step << 6;
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Generate 64 independent always blocks using generate
|
||||
//////////////////////////////////////////////////////////////
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < 64; i = i + 1) begin : ramp_chan
|
||||
reg [7:0] ramp_r;
|
||||
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
ramp_r <= 8'b0;
|
||||
end
|
||||
else if (fixed) begin
|
||||
ramp_r <= fixed_value;
|
||||
end
|
||||
else if (ifs == 32'b0) begin
|
||||
// Special mode: ifs == 0
|
||||
if (cen & ~ramp_add_en) begin
|
||||
// Initial phase loading: channel i gets (i+1)*step
|
||||
ramp_r <= (i + 1) * step;
|
||||
end
|
||||
else if (ramp_add_en) begin
|
||||
// Add large step each cycle (select 64¡Ástep or 32¡Ástep according to dac_mode_sel[1])
|
||||
ramp_r <= ramp_r + (dac_mode_sel[1] ? step64_w : step32_w);
|
||||
end
|
||||
else begin
|
||||
// Hold current value
|
||||
ramp_r <= ramp_r;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
// Normal mode: add step every ifs cycles
|
||||
if (ramp_add_en) begin
|
||||
ramp_r <= ramp_r + step;
|
||||
end
|
||||
else begin
|
||||
ramp_r <= ramp_r;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Connect internal register to output port
|
||||
assign ramp[i] = ramp_r;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Output valid signal
|
||||
//////////////////////////////////////////////////////////////
|
||||
reg en_dly;
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) en_dly <= 1'b0;
|
||||
else en_dly <= cen | fixed;
|
||||
end
|
||||
|
||||
assign ramp_vld = en_dly;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,342 @@
|
|||
/*
|
||||
Copyright 2018-2020 Nuclei System Technology, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//=====================================================================
|
||||
//
|
||||
// Designer : Bob Hu
|
||||
//
|
||||
// Description:
|
||||
// All of the general DFF and Latch modules
|
||||
//
|
||||
// ====================================================================
|
||||
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// ===========================================================================
|
||||
//
|
||||
// Description:
|
||||
// Verilog module sirv_gnrl DFF with Load-enable and Reset
|
||||
// Default reset value is 1
|
||||
//
|
||||
// ===========================================================================
|
||||
`define DISABLE_SV_ASSERTION
|
||||
`define dly #0.2
|
||||
module sirv_gnrl_dfflrs # (
|
||||
parameter DW = 32
|
||||
) (
|
||||
|
||||
input lden,
|
||||
input [DW-1:0] dnxt,
|
||||
output [DW-1:0] qout,
|
||||
|
||||
input clk,
|
||||
input rst_n
|
||||
);
|
||||
|
||||
reg [DW-1:0] qout_r;
|
||||
|
||||
always @(posedge clk or negedge rst_n)
|
||||
begin : DFFLRS_PROC
|
||||
if (rst_n == 1'b0)
|
||||
qout_r <= {DW{1'b1}};
|
||||
else if (lden == 1'b1)
|
||||
qout_r <= `dly dnxt;
|
||||
end
|
||||
|
||||
assign qout = qout_r;
|
||||
|
||||
`ifndef FPGA_SOURCE//{
|
||||
`ifndef DISABLE_SV_ASSERTION//{
|
||||
//synopsys translate_off
|
||||
sirv_gnrl_xchecker # (
|
||||
.DW(1)
|
||||
) sirv_gnrl_xchecker(
|
||||
.i_dat(lden),
|
||||
.clk (clk)
|
||||
);
|
||||
//synopsys translate_on
|
||||
`endif//}
|
||||
`endif//}
|
||||
|
||||
|
||||
endmodule
|
||||
// ===========================================================================
|
||||
//
|
||||
// Description:
|
||||
// Verilog module sirv_gnrl DFF with Load-enable and Reset
|
||||
// Default reset value is 0
|
||||
//
|
||||
// ===========================================================================
|
||||
|
||||
module sirv_gnrl_dfflr # (
|
||||
parameter DW = 32
|
||||
) (
|
||||
|
||||
input lden,
|
||||
input [DW-1:0] dnxt,
|
||||
output [DW-1:0] qout,
|
||||
|
||||
input clk,
|
||||
input rst_n
|
||||
);
|
||||
|
||||
reg [DW-1:0] qout_r;
|
||||
|
||||
always @(posedge clk or negedge rst_n)
|
||||
begin : DFFLR_PROC
|
||||
if (rst_n == 1'b0)
|
||||
qout_r <= {DW{1'b0}};
|
||||
else if (lden == 1'b1)
|
||||
qout_r <= `dly dnxt;
|
||||
end
|
||||
|
||||
assign qout = qout_r;
|
||||
|
||||
`ifndef FPGA_SOURCE//{
|
||||
`ifndef DISABLE_SV_ASSERTION//{
|
||||
//synopsys translate_off
|
||||
sirv_gnrl_xchecker # (
|
||||
.DW(1)
|
||||
) sirv_gnrl_xchecker(
|
||||
.i_dat(lden),
|
||||
.clk (clk)
|
||||
);
|
||||
//synopsys translate_on
|
||||
`endif//}
|
||||
`endif//}
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ===========================================================================
|
||||
//
|
||||
// Description:
|
||||
// Verilog module sirv_gnrl DFF with Load-enable and Reset
|
||||
// Default reset value is input
|
||||
//
|
||||
// ===========================================================================
|
||||
|
||||
module sirv_gnrl_dfflrd # (
|
||||
parameter DW = 32
|
||||
) (
|
||||
input [DW-1:0] init,
|
||||
input lden,
|
||||
input [DW-1:0] dnxt,
|
||||
output [DW-1:0] qout,
|
||||
|
||||
input clk,
|
||||
input rst_n
|
||||
);
|
||||
|
||||
reg [DW-1:0] qout_r;
|
||||
|
||||
always @(posedge clk or negedge rst_n)
|
||||
begin : DFFLR_PROC
|
||||
if (rst_n == 1'b0)
|
||||
qout_r <= init;
|
||||
else if (lden == 1'b1)
|
||||
qout_r <= `dly dnxt;
|
||||
end
|
||||
|
||||
assign qout = qout_r;
|
||||
|
||||
`ifndef FPGA_SOURCE//{
|
||||
`ifndef DISABLE_SV_ASSERTION//{
|
||||
//synopsys translate_off
|
||||
sirv_gnrl_xchecker # (
|
||||
.DW(1)
|
||||
) sirv_gnrl_xchecker(
|
||||
.i_dat(lden),
|
||||
.clk (clk)
|
||||
);
|
||||
//synopsys translate_on
|
||||
`endif//}
|
||||
`endif//}
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ===========================================================================
|
||||
//
|
||||
// Description:
|
||||
// Verilog module sirv_gnrl DFF with Load-enable, no reset
|
||||
//
|
||||
// ===========================================================================
|
||||
|
||||
module sirv_gnrl_dffl # (
|
||||
parameter DW = 32
|
||||
) (
|
||||
|
||||
input lden,
|
||||
input [DW-1:0] dnxt,
|
||||
output [DW-1:0] qout,
|
||||
|
||||
input clk
|
||||
);
|
||||
|
||||
reg [DW-1:0] qout_r;
|
||||
|
||||
always @(posedge clk)
|
||||
begin : DFFL_PROC
|
||||
if (lden == 1'b1)
|
||||
qout_r <= `dly dnxt;
|
||||
end
|
||||
|
||||
assign qout = qout_r;
|
||||
|
||||
`ifndef FPGA_SOURCE//{
|
||||
`ifndef DISABLE_SV_ASSERTION//{
|
||||
//synopsys translate_off
|
||||
sirv_gnrl_xchecker # (
|
||||
.DW(1)
|
||||
) sirv_gnrl_xchecker(
|
||||
.i_dat(lden),
|
||||
.clk (clk)
|
||||
);
|
||||
//synopsys translate_on
|
||||
`endif//}
|
||||
`endif//}
|
||||
|
||||
|
||||
endmodule
|
||||
// ===========================================================================
|
||||
//
|
||||
// Description:
|
||||
// Verilog module sirv_gnrl DFF with Reset, no load-enable
|
||||
// Default reset value is 1
|
||||
//
|
||||
// ===========================================================================
|
||||
|
||||
module sirv_gnrl_dffrs # (
|
||||
parameter DW = 32
|
||||
) (
|
||||
|
||||
input [DW-1:0] dnxt,
|
||||
output [DW-1:0] qout,
|
||||
|
||||
input clk,
|
||||
input rst_n
|
||||
);
|
||||
|
||||
reg [DW-1:0] qout_r;
|
||||
|
||||
always @(posedge clk or negedge rst_n)
|
||||
begin : DFFRS_PROC
|
||||
if (rst_n == 1'b0)
|
||||
qout_r <= {DW{1'b1}};
|
||||
else
|
||||
qout_r <= `dly dnxt;
|
||||
end
|
||||
|
||||
assign qout = qout_r;
|
||||
|
||||
endmodule
|
||||
// ===========================================================================
|
||||
//
|
||||
// Description:
|
||||
// Verilog module sirv_gnrl DFF with Reset, no load-enable
|
||||
// Default reset value is 0
|
||||
//
|
||||
// ===========================================================================
|
||||
|
||||
module sirv_gnrl_dffr # (
|
||||
parameter DW = 32
|
||||
) (
|
||||
|
||||
input [DW-1:0] dnxt,
|
||||
output [DW-1:0] qout,
|
||||
|
||||
input clk,
|
||||
input rst_n
|
||||
);
|
||||
|
||||
reg [DW-1:0] qout_r;
|
||||
|
||||
always @(posedge clk or negedge rst_n)
|
||||
begin : DFFR_PROC
|
||||
if (rst_n == 1'b0)
|
||||
qout_r <= {DW{1'b0}};
|
||||
else
|
||||
qout_r <= `dly dnxt;
|
||||
end
|
||||
|
||||
assign qout = qout_r;
|
||||
|
||||
endmodule
|
||||
// ===========================================================================
|
||||
//
|
||||
// Description:
|
||||
// Verilog module for general latch
|
||||
//
|
||||
// ===========================================================================
|
||||
|
||||
module sirv_gnrl_ltch # (
|
||||
parameter DW = 32
|
||||
) (
|
||||
|
||||
//input test_mode,
|
||||
input lden,
|
||||
input [DW-1:0] dnxt,
|
||||
output [DW-1:0] qout
|
||||
);
|
||||
|
||||
reg [DW-1:0] qout_r;
|
||||
|
||||
always @ *
|
||||
begin : LTCH_PROC
|
||||
if (lden == 1'b1)
|
||||
qout_r <= dnxt;
|
||||
end
|
||||
|
||||
//assign qout = test_mode ? dnxt : qout_r;
|
||||
assign qout = qout_r;
|
||||
|
||||
`ifndef FPGA_SOURCE//{
|
||||
`ifndef DISABLE_SV_ASSERTION//{
|
||||
//synopsys translate_off
|
||||
always_comb
|
||||
begin
|
||||
CHECK_THE_X_VALUE:
|
||||
assert (lden !== 1'bx)
|
||||
else $fatal ("\n Error: Oops, detected a X value!!! This should never happen. \n");
|
||||
end
|
||||
|
||||
//synopsys translate_on
|
||||
`endif//}
|
||||
`endif//}
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
module sirv_gnrl_edffr #(parameter type T = logic) (
|
||||
input T dnxt,
|
||||
output T qout,
|
||||
input clk, rst_n
|
||||
);
|
||||
|
||||
T qout_r;
|
||||
|
||||
always_ff @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) qout_r <= T'('0);
|
||||
else qout_r <= `dly dnxt;
|
||||
end
|
||||
assign qout = qout_r;
|
||||
endmodule
|
||||
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
Copyright 2018-2020 Nuclei System Technology, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//=====================================================================
|
||||
//
|
||||
// Designer : Bob Hu
|
||||
//
|
||||
// Description:
|
||||
// Verilog module for X checker
|
||||
//
|
||||
// ====================================================================
|
||||
|
||||
|
||||
`ifndef FPGA_SOURCE//{
|
||||
`ifndef DISABLE_SV_ASSERTION//{
|
||||
//synopsys translate_off
|
||||
module sirv_gnrl_xchecker # (
|
||||
parameter DW = 32
|
||||
) (
|
||||
input [DW-1:0] i_dat,
|
||||
input clk
|
||||
);
|
||||
|
||||
|
||||
CHECK_THE_X_VALUE:
|
||||
assert property (@(posedge clk)
|
||||
((^(i_dat)) !== 1'bx)
|
||||
)
|
||||
else $fatal ("\n Error: Oops, detected a X value!!! This should never happen. \n");
|
||||
|
||||
endmodule
|
||||
//synopsys translate_on
|
||||
`endif//}
|
||||
`endif//}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
//+FHDR--------------------------------------------------------------------------------------------------------
|
||||
// Company:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// File Name : syncer.v
|
||||
// Department :
|
||||
// Author : PWY
|
||||
// Author's Tel :
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Relese History
|
||||
// Version Date Author Description
|
||||
// 0.1 2024-03-13 PWY AWG dedicated register file
|
||||
// 0.2 2024-05-13 PWY
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Keywords :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Parameter
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Target Device:
|
||||
// Tool versions:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Reuse Issues
|
||||
// Reset Strategy:
|
||||
// Clock Domains:
|
||||
// Critical Timing:
|
||||
// Asynchronous I/F:
|
||||
// Synthesizable (y/n):
|
||||
// Other:
|
||||
//-FHDR--------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
module syncer # (
|
||||
parameter width = 1
|
||||
,parameter stage = 2
|
||||
)
|
||||
(
|
||||
input clk_d
|
||||
,input rstn_d
|
||||
,input [width-1:0] data_s
|
||||
,output [width-1:0] data_d
|
||||
);
|
||||
|
||||
generate
|
||||
genvar i;
|
||||
wire [width-1:0] data_temp[stage-1:0];
|
||||
sirv_gnrl_dffr #(width) data_temp0_dffr (data_s ,data_temp[0], clk_d, rstn_d);
|
||||
for(i=1;i<stage;i=i+1) begin: SYNCER
|
||||
sirv_gnrl_dffr #(width) data_tempn0_dffr (data_temp[i-1] ,data_temp[i], clk_d, rstn_d);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign data_d = data_temp[stage-1];
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,977 @@
|
|||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2026/02/28 19:57:30
|
||||
// Design Name:
|
||||
// Module Name: dac_regfile
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
// Revision Date: 2026/02/28 19:57:30
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// -- Register address offset macros
|
||||
// -----------------------------------------------------------
|
||||
//Prbs_en Ctrl Register
|
||||
|
||||
`define RTERMR 16'h0000
|
||||
`define PRBSENR 16'h0004
|
||||
`define SET0R 16'h0008
|
||||
`define SET1R 16'h000C
|
||||
`define SET2R 16'h0010
|
||||
`define SET3R 16'h0014
|
||||
`define SET4R 16'h0018
|
||||
`define SET5R 16'h001C
|
||||
`define SET6R 16'h0020
|
||||
`define SET7R 16'h0024
|
||||
`define SET8R 16'h0028
|
||||
`define SET9R 16'h002C
|
||||
`define SET10R 16'h0030
|
||||
`define SET11R 16'h0034
|
||||
`define SET12R 16'h0038
|
||||
`define SET13R 16'h003C
|
||||
`define SET14R 16'h0040
|
||||
`define SET15R 16'h0044
|
||||
`define SET16R 16'h0048
|
||||
`define SET17R 16'h004C
|
||||
`define SET18R 16'h0050
|
||||
`define SET19R 16'h0054
|
||||
`define SET20R 16'h0058
|
||||
`define SET21R 16'h005C
|
||||
`define SET22R 16'h0060
|
||||
`define SET23R 16'h0064
|
||||
`define SET24R 16'h0068
|
||||
`define SET25R 16'h006C
|
||||
`define SET26R 16'h0070
|
||||
`define SET27R 16'h0074
|
||||
`define SET28R 16'h0078
|
||||
`define SET29R 16'h007C
|
||||
`define SET30R 16'h0080
|
||||
`define SET31R 16'h0084
|
||||
`define CASADDRR 16'h0088
|
||||
`define CASDWR 16'h008C
|
||||
`define IMCTR 16'h0090
|
||||
`define IBLEEDCTR 16'h0094
|
||||
`define ICLKCMLR 16'h0098
|
||||
`define CURRSVR0 16'h009C
|
||||
`define CURRSVR1 16'h00A0
|
||||
`define VERSIONR 16'h00A4
|
||||
|
||||
module dac_regfile #(
|
||||
parameter DACVERSION = 32'h2026_0510
|
||||
)
|
||||
(
|
||||
//system port
|
||||
input clk // System Main Clock
|
||||
,input rstn // Spi Reset active low
|
||||
//rw op port
|
||||
,input [31 :0] wrdata // write data
|
||||
,input wren // write enable
|
||||
,input [15 :0] rwaddr // read & write address
|
||||
,input rden // read enable
|
||||
,output [31 :0] rddata // read data
|
||||
|
||||
,output [3 :0] Rterm // R_Terminate
|
||||
,output PrbsEn // Prbs_en
|
||||
,output [14 :0] Set [63:0]
|
||||
|
||||
,output [2 :0] CasAddr
|
||||
,output [2 :0] CasDw
|
||||
,output [9 :0] IMainCtrl
|
||||
,output [3 :0] IBleedCtrl
|
||||
,output [3 :0] ICkCml
|
||||
,output [31 :0] CurRsv0
|
||||
,output [31 :0] CurRsv1
|
||||
);
|
||||
|
||||
localparam L = 1'b0,
|
||||
H = 1'b1;
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Register Default Vaule
|
||||
// ------------------------------------------------------
|
||||
wire [3 :0] rtermrdft = 4'b0001 ; // RTERMR 16'h0000
|
||||
wire [0 :0] prbsrdft = 1'b0 ; // PRBSENR 16'h0004
|
||||
wire [31:0] set0rdft = {16'h05,16'h3B} ; // SET0R 16'h0008
|
||||
wire [31:0] set1rdft = {16'h49,16'h19} ; // SET1R 16'h000C
|
||||
wire [31:0] set2rdft = {16'h4D,16'h9D} ; // SET2R 16'h0010
|
||||
wire [31:0] set3rdft = {16'h89,16'h41} ; // SET3R 16'h0014
|
||||
wire [31:0] set4rdft = {16'h40,16'hA6} ; // SET4R 16'h0018
|
||||
wire [31:0] set5rdft = {16'h55,16'h14} ; // SET5R 16'h001C
|
||||
wire [31:0] set6rdft = {16'h03,16'h97} ; // SET6R 16'h0020
|
||||
wire [31:0] set7rdft = {16'h2A,16'hD1} ; // SET7R 16'h0024
|
||||
wire [31:0] set8rdft = {16'h42,16'h78} ; // SET8R 16'h0028
|
||||
wire [31:0] set9rdft = {16'h12,16'h33} ; // SET9R 16'h002C
|
||||
wire [31:0] set10rdft = {16'h33,16'h01} ; // SET10R 16'h0030
|
||||
wire [31:0] set11rdft = {16'hD0,16'h15} ; // SET11R 16'h0034
|
||||
wire [31:0] set12rdft = {16'hB9,16'h15} ; // SET12R 16'h0038
|
||||
wire [31:0] set13rdft = {16'hDF,16'h38} ; // SET13R 16'h003C
|
||||
wire [31:0] set14rdft = {16'h35,16'h7C} ; // SET14R 16'h0040
|
||||
wire [31:0] set15rdft = {16'hAA,16'hDF} ; // SET15R 16'h0044
|
||||
wire [31:0] set16rdft = {16'h66,16'h83} ; // SET16R 16'h0048
|
||||
wire [31:0] set17rdft = {16'hC2,16'h8F} ; // SET17R 16'h004C
|
||||
wire [31:0] set18rdft = {16'hC4,16'hD0} ; // SET18R 16'h0050
|
||||
wire [31:0] set19rdft = {16'hA3,16'hAE} ; // SET19R 16'h0054
|
||||
wire [31:0] set20rdft = {16'h3F,16'hA0} ; // SET20R 16'h0058
|
||||
wire [31:0] set21rdft = {16'hCD,16'h39} ; // SET21R 16'h005C
|
||||
wire [31:0] set22rdft = {16'h30,16'hF4} ; // SET22R 16'h0060
|
||||
wire [31:0] set23rdft = {16'h24,16'hD6} ; // SET23R 16'h0064
|
||||
wire [31:0] set24rdft = {16'h89,16'h26} ; // SET24R 16'h0068
|
||||
wire [31:0] set25rdft = {16'h7F,16'h05} ; // SET25R 16'h006C
|
||||
wire [31:0] set26rdft = {16'h28,16'hF9} ; // SET26R 16'h0070
|
||||
wire [31:0] set27rdft = {16'hC9,16'hCC} ; // SET27R 16'h0074
|
||||
wire [31:0] set28rdft = {16'h8E,16'hEF} ; // SET28R 16'h0078
|
||||
wire [31:0] set29rdft = {16'hC0,16'h5B} ; // SET29R 16'h007C
|
||||
wire [31:0] set30rdft = {16'hD6,16'h08} ; // SET30R 16'h0080
|
||||
wire [31:0] set31rdft = {16'h20,16'hB0} ; // SET31R 16'h0084
|
||||
wire [2 :0] casaddrrdft = 3'b111 ; // CASADDRR 16'h0088
|
||||
wire [2 :0] casdwrdft = 3'b111 ; // CASDWR 16'h008C
|
||||
wire [9 :0] imctrdft = 10'b11_0000_0000 ; // IMCTR 16'h0090
|
||||
wire [3 :0] ibleedctrdft = 4'b0111 ; // IBLEEDCTR 16'h0094
|
||||
wire [3 :0] iclkcmlrdft = 4'b0111 ; // ICLKCMLR 16'h0098
|
||||
wire [31:0] currsvr0dft = 32'h0 ; // CURRSVR0 16'h009C
|
||||
wire [31:0] currsvr1dft = 32'h0 ; // CURRSVR1 16'h00A0
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Register enable (select) wires
|
||||
// ------------------------------------------------------
|
||||
wire rtermren ; // RTERMR Enable
|
||||
wire prbsren ; // PRBSENR Enable
|
||||
wire set0ren ; // SET0R Enable
|
||||
wire set1ren ; // SET1R Enable
|
||||
wire set2ren ; // SET2R Enable
|
||||
wire set3ren ; // SET3R Enable
|
||||
wire set4ren ; // SET4R Enable
|
||||
wire set5ren ; // SET5R Enable
|
||||
wire set6ren ; // SET6R Enable
|
||||
wire set7ren ; // SET7R Enable
|
||||
wire set8ren ; // SET8R Enable
|
||||
wire set9ren ; // SET9R Enable
|
||||
wire set10ren ; // SET10R Enable
|
||||
wire set11ren ; // SET11R Enable
|
||||
wire set12ren ; // SET12R Enable
|
||||
wire set13ren ; // SET13R Enable
|
||||
wire set14ren ; // SET14R Enable
|
||||
wire set15ren ; // SET15R Enable
|
||||
wire set16ren ; // SET16R Enable
|
||||
wire set17ren ; // SET17R Enable
|
||||
wire set18ren ; // SET18R Enable
|
||||
wire set19ren ; // SET19R Enable
|
||||
wire set20ren ; // SET20R Enable
|
||||
wire set21ren ; // SET21R Enable
|
||||
wire set22ren ; // SET22R Enable
|
||||
wire set23ren ; // SET23R Enable
|
||||
wire set24ren ; // SET24R Enable
|
||||
wire set25ren ; // SET25R Enable
|
||||
wire set26ren ; // SET26R Enable
|
||||
wire set27ren ; // SET27R Enable
|
||||
wire set28ren ; // SET28R Enable
|
||||
wire set29ren ; // SET29R Enable
|
||||
wire set30ren ; // SET30R Enable
|
||||
wire set31ren ; // SET31R Enable
|
||||
wire casaddrren ; // CASADDRR Enable
|
||||
wire casdwren ; // CASDWR Enable
|
||||
wire imctren ; // IMCTR Enable
|
||||
wire ibleedctren ; // IBLEEDCTR Enable
|
||||
wire iclkcmlren ; // ICLKCMLR Enable
|
||||
wire currsvr0en ; // CURRSVR0 Enable
|
||||
wire currsvr1en ; // CURRSVR1 Enable
|
||||
wire verren ; // VERSIONR Enable
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Register write enable wires
|
||||
// ------------------------------------------------------
|
||||
wire rtermrwe ; // RTERMR Write Enable
|
||||
wire prbsrwe ; // PRBSENR Write Enable
|
||||
wire set0rwe ; // SET0R Write Enable
|
||||
wire set1rwe ; // SET1R Write Enable
|
||||
wire set2rwe ; // SET2R Write Enable
|
||||
wire set3rwe ; // SET3R Write Enable
|
||||
wire set4rwe ; // SET4R Write Enable
|
||||
wire set5rwe ; // SET5R Write Enable
|
||||
wire set6rwe ; // SET6R Write Enable
|
||||
wire set7rwe ; // SET7R Write Enable
|
||||
wire set8rwe ; // SET8R Write Enable
|
||||
wire set9rwe ; // SET9R Write Enable
|
||||
wire set10rwe ; // SET10R Write Enable
|
||||
wire set11rwe ; // SET11R Write Enable
|
||||
wire set12rwe ; // SET12R Write Enable
|
||||
wire set13rwe ; // SET13R Write Enable
|
||||
wire set14rwe ; // SET14R Write Enable
|
||||
wire set15rwe ; // SET15R Write Enable
|
||||
wire set16rwe ; // SET16R Write Enable
|
||||
wire set17rwe ; // SET17R Write Enable
|
||||
wire set18rwe ; // SET18R Write Enable
|
||||
wire set19rwe ; // SET19R Write Enable
|
||||
wire set20rwe ; // SET20R Write Enable
|
||||
wire set21rwe ; // SET21R Write Enable
|
||||
wire set22rwe ; // SET22R Write Enable
|
||||
wire set23rwe ; // SET23R Write Enable
|
||||
wire set24rwe ; // SET24R Write Enable
|
||||
wire set25rwe ; // SET25R Write Enable
|
||||
wire set26rwe ; // SET26R Write Enable
|
||||
wire set27rwe ; // SET27R Write Enable
|
||||
wire set28rwe ; // SET28R Write Enable
|
||||
wire set29rwe ; // SET29R Write Enable
|
||||
wire set30rwe ; // SET30R Write Enable
|
||||
wire set31rwe ; // SET31R Write Enable
|
||||
wire casaddrrwe ; // CASADDRR Write Enable
|
||||
wire casdwrwe ; // CASDWR Write Enable
|
||||
wire imctrwe ; // IMCTR Write Enable
|
||||
wire ibleedctrwe ; // IBLEEDCTR Write Enable
|
||||
wire iclkcmlrwe ; // ICLKCMLR Write Enable
|
||||
wire currsvr0we ; // CURRSVR0 Write Enable
|
||||
wire currsvr1we ; // CURRSVR1 Write Enable
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Misc Registers
|
||||
// ------------------------------------------------------
|
||||
wire [3 :0] rtermr ; // RTERMR Register, Default vaule is 4'b0001
|
||||
wire [0 :0] prbsr ; // PRBSENR Register, Default vaule is 1'b0
|
||||
wire [31:0] set0r ; // SET0R Register, Default vaule is {16'h05,16'h3B}
|
||||
wire [31:0] set1r ; // SET1R Register, Default vaule is {16'h49,16'h19}
|
||||
wire [31:0] set2r ; // SET2R Register, Default vaule is {16'h4D,16'h9D}
|
||||
wire [31:0] set3r ; // SET3R Register, Default vaule is {16'h89,16'h41}
|
||||
wire [31:0] set4r ; // SET4R Register, Default vaule is {16'h40,16'hA6}
|
||||
wire [31:0] set5r ; // SET5R Register, Default vaule is {16'h55,16'h14}
|
||||
wire [31:0] set6r ; // SET6R Register, Default vaule is {16'h03,16'h97}
|
||||
wire [31:0] set7r ; // SET7R Register, Default vaule is {16'h2A,16'hD1}
|
||||
wire [31:0] set8r ; // SET8R Register, Default vaule is {16'h42,16'h78}
|
||||
wire [31:0] set9r ; // SET9R Register, Default vaule is {16'h12,16'h33}
|
||||
wire [31:0] set10r ; // SET10R Register, Default vaule is {16'h33,16'h01}
|
||||
wire [31:0] set11r ; // SET11R Register, Default vaule is {16'hD0,16'h15}
|
||||
wire [31:0] set12r ; // SET12R Register, Default vaule is {16'hB9,16'h15}
|
||||
wire [31:0] set13r ; // SET13R Register, Default vaule is {16'hDF,16'h38}
|
||||
wire [31:0] set14r ; // SET14R Register, Default vaule is {16'h35,16'h7C}
|
||||
wire [31:0] set15r ; // SET15R Register, Default vaule is {16'hAA,16'hDF}
|
||||
wire [31:0] set16r ; // SET16R Register, Default vaule is {16'h66,16'h83}
|
||||
wire [31:0] set17r ; // SET17R Register, Default vaule is {16'hC2,16'h8F}
|
||||
wire [31:0] set18r ; // SET18R Register, Default vaule is {16'hC4,16'hD0}
|
||||
wire [31:0] set19r ; // SET19R Register, Default vaule is {16'hA3,16'hAE}
|
||||
wire [31:0] set20r ; // SET20R Register, Default vaule is {16'h3F,16'hA0}
|
||||
wire [31:0] set21r ; // SET21R Register, Default vaule is {16'hCD,16'h39}
|
||||
wire [31:0] set22r ; // SET22R Register, Default vaule is {16'h30,16'hF4}
|
||||
wire [31:0] set23r ; // SET23R Register, Default vaule is {16'h24,16'hD6}
|
||||
wire [31:0] set24r ; // SET24R Register, Default vaule is {16'h89,16'h26}
|
||||
wire [31:0] set25r ; // SET25R Register, Default vaule is {16'h7F,16'h05}
|
||||
wire [31:0] set26r ; // SET26R Register, Default vaule is {16'h28,16'hF9}
|
||||
wire [31:0] set27r ; // SET27R Register, Default vaule is {16'hC9,16'hCC}
|
||||
wire [31:0] set28r ; // SET28R Register, Default vaule is {16'h8E,16'hEF}
|
||||
wire [31:0] set29r ; // SET29R Register, Default vaule is {16'hC0,16'h5B}
|
||||
wire [31:0] set30r ; // SET30R Register, Default vaule is {16'hD6,16'h08}
|
||||
wire [31:0] set31r ; // SET31R Register, Default vaule is {16'h20,16'hB0}
|
||||
wire [2 :0] casaddrr ; // CASADDRR Register, Default vaule is 3'b111
|
||||
wire [2 :0] casdwr ; // CASDWR Register, Default vaule is 3'b111
|
||||
wire [9 :0] imctr ; // IMCTR Register, Default vaule is 9'b11_0000_0000
|
||||
wire [3 :0] ibleedctr ; // IBLEEDCTR Register, Default vaule is 4'b0111
|
||||
wire [3 :0] iclkcmlr ; // ICLKCMLR Register, Default vaule is 4'b0111
|
||||
wire [31:0] currsvr0 ; // CURRSVR0 Register, Default vaule is 32'h0
|
||||
wire [31:0] currsvr1 ; // CURRSVR1 Register, Default vaule is 32'h0
|
||||
|
||||
reg [31 :0] rddata_reg ;
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Address decoder
|
||||
//
|
||||
// Decodes the register address offset input(reg_addr)
|
||||
// to produce enable (select) signals for each of the
|
||||
// SW-registers in the macrocell. The reg_addr input
|
||||
// is bits [15:0] of the paddr bus.
|
||||
// -------------------------------------------------- ----
|
||||
assign rtermren = (rwaddr[15:2] == `RTERMR >>2) ? 1'b1 : 1'b0; // RTERMR Enable
|
||||
assign prbsren = (rwaddr[15:2] == `PRBSENR >>2) ? 1'b1 : 1'b0; // PRBSENR Enable
|
||||
assign set0ren = (rwaddr[15:2] == `SET0R >>2) ? 1'b1 : 1'b0; // SET0R Enable
|
||||
assign set1ren = (rwaddr[15:2] == `SET1R >>2) ? 1'b1 : 1'b0; // SET1R Enable
|
||||
assign set2ren = (rwaddr[15:2] == `SET2R >>2) ? 1'b1 : 1'b0; // SET2R Enable
|
||||
assign set3ren = (rwaddr[15:2] == `SET3R >>2) ? 1'b1 : 1'b0; // SET3R Enable
|
||||
assign set4ren = (rwaddr[15:2] == `SET4R >>2) ? 1'b1 : 1'b0; // SET4R Enable
|
||||
assign set5ren = (rwaddr[15:2] == `SET5R >>2) ? 1'b1 : 1'b0; // SET5R Enable
|
||||
assign set6ren = (rwaddr[15:2] == `SET6R >>2) ? 1'b1 : 1'b0; // SET6R Enable
|
||||
assign set7ren = (rwaddr[15:2] == `SET7R >>2) ? 1'b1 : 1'b0; // SET7R Enable
|
||||
assign set8ren = (rwaddr[15:2] == `SET8R >>2) ? 1'b1 : 1'b0; // SET8R Enable
|
||||
assign set9ren = (rwaddr[15:2] == `SET9R >>2) ? 1'b1 : 1'b0; // SET9R Enable
|
||||
assign set10ren = (rwaddr[15:2] == `SET10R >>2) ? 1'b1 : 1'b0; // SET10R Enable
|
||||
assign set11ren = (rwaddr[15:2] == `SET11R >>2) ? 1'b1 : 1'b0; // SET11R Enable
|
||||
assign set12ren = (rwaddr[15:2] == `SET12R >>2) ? 1'b1 : 1'b0; // SET12R Enable
|
||||
assign set13ren = (rwaddr[15:2] == `SET13R >>2) ? 1'b1 : 1'b0; // SET13R Enable
|
||||
assign set14ren = (rwaddr[15:2] == `SET14R >>2) ? 1'b1 : 1'b0; // SET14R Enable
|
||||
assign set15ren = (rwaddr[15:2] == `SET15R >>2) ? 1'b1 : 1'b0; // SET15R Enable
|
||||
assign set16ren = (rwaddr[15:2] == `SET16R >>2) ? 1'b1 : 1'b0; // SET16R Enable
|
||||
assign set17ren = (rwaddr[15:2] == `SET17R >>2) ? 1'b1 : 1'b0; // SET17R Enable
|
||||
assign set18ren = (rwaddr[15:2] == `SET18R >>2) ? 1'b1 : 1'b0; // SET18R Enable
|
||||
assign set19ren = (rwaddr[15:2] == `SET19R >>2) ? 1'b1 : 1'b0; // SET19R Enable
|
||||
assign set20ren = (rwaddr[15:2] == `SET20R >>2) ? 1'b1 : 1'b0; // SET20R Enable
|
||||
assign set21ren = (rwaddr[15:2] == `SET21R >>2) ? 1'b1 : 1'b0; // SET21R Enable
|
||||
assign set22ren = (rwaddr[15:2] == `SET22R >>2) ? 1'b1 : 1'b0; // SET22R Enable
|
||||
assign set23ren = (rwaddr[15:2] == `SET23R >>2) ? 1'b1 : 1'b0; // SET23R Enable
|
||||
assign set24ren = (rwaddr[15:2] == `SET24R >>2) ? 1'b1 : 1'b0; // SET24R Enable
|
||||
assign set25ren = (rwaddr[15:2] == `SET25R >>2) ? 1'b1 : 1'b0; // SET25R Enable
|
||||
assign set26ren = (rwaddr[15:2] == `SET26R >>2) ? 1'b1 : 1'b0; // SET26R Enable
|
||||
assign set27ren = (rwaddr[15:2] == `SET27R >>2) ? 1'b1 : 1'b0; // SET27R Enable
|
||||
assign set28ren = (rwaddr[15:2] == `SET28R >>2) ? 1'b1 : 1'b0; // SET28R Enable
|
||||
assign set29ren = (rwaddr[15:2] == `SET29R >>2) ? 1'b1 : 1'b0; // SET29R Enable
|
||||
assign set30ren = (rwaddr[15:2] == `SET30R >>2) ? 1'b1 : 1'b0; // SET30R Enable
|
||||
assign set31ren = (rwaddr[15:2] == `SET31R >>2) ? 1'b1 : 1'b0; // SET31R Enable
|
||||
assign casaddrren = (rwaddr[15:2] == `CASADDRR >>2) ? 1'b1 : 1'b0; // CASADDRR Enable
|
||||
assign casdwren = (rwaddr[15:2] == `CASDWR >>2) ? 1'b1 : 1'b0; // CASDWR Enable
|
||||
assign imctren = (rwaddr[15:2] == `IMCTR >>2) ? 1'b1 : 1'b0; // IMCTR Enable
|
||||
assign ibleedctren = (rwaddr[15:2] == `IBLEEDCTR >>2) ? 1'b1 : 1'b0; // IBLEEDCTR Enable
|
||||
assign iclkcmlren = (rwaddr[15:2] == `ICLKCMLR >>2) ? 1'b1 : 1'b0; // ICLKCMLR Enable
|
||||
assign currsvr0en = (rwaddr[15:2] == `CURRSVR0 >>2) ? 1'b1 : 1'b0; // CURRSVR0 Enable
|
||||
assign currsvr1en = (rwaddr[15:2] == `CURRSVR1 >>2) ? 1'b1 : 1'b0; // CURRSVR1 Enable
|
||||
assign verren = (rwaddr[15:2] == `VERSIONR >>2) ? 1'b1 : 1'b0; // VERSIONR Enable
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Write enable signals
|
||||
//
|
||||
// Write enable signals for writable SW-registers.
|
||||
// The write enable for each register is the ANDed
|
||||
// result of the register enable and the input reg_wren
|
||||
// ------------------------------------------------------
|
||||
assign rtermrwe = rtermren & wren; // RTERMR Write Enable
|
||||
assign prbsrwe = prbsren & wren; // PRBSENR Write Enable
|
||||
assign set0rwe = set0ren & wren; // SET0R Write Enable
|
||||
assign set1rwe = set1ren & wren; // SET1R Write Enable
|
||||
assign set2rwe = set2ren & wren; // SET2R Write Enable
|
||||
assign set3rwe = set3ren & wren; // SET3R Write Enable
|
||||
assign set4rwe = set4ren & wren; // SET4R Write Enable
|
||||
assign set5rwe = set5ren & wren; // SET5R Write Enable
|
||||
assign set6rwe = set6ren & wren; // SET6R Write Enable
|
||||
assign set7rwe = set7ren & wren; // SET7R Write Enable
|
||||
assign set8rwe = set8ren & wren; // SET8R Write Enable
|
||||
assign set9rwe = set9ren & wren; // SET9R Write Enable
|
||||
assign set10rwe = set10ren & wren; // SET10R Write Enable
|
||||
assign set11rwe = set11ren & wren; // SET11R Write Enable
|
||||
assign set12rwe = set12ren & wren; // SET12R Write Enable
|
||||
assign set13rwe = set13ren & wren; // SET13R Write Enable
|
||||
assign set14rwe = set14ren & wren; // SET14R Write Enable
|
||||
assign set15rwe = set15ren & wren; // SET15R Write Enable
|
||||
assign set16rwe = set16ren & wren; // SET16R Write Enable
|
||||
assign set17rwe = set17ren & wren; // SET17R Write Enable
|
||||
assign set18rwe = set18ren & wren; // SET18R Write Enable
|
||||
assign set19rwe = set19ren & wren; // SET19R Write Enable
|
||||
assign set20rwe = set20ren & wren; // SET20R Write Enable
|
||||
assign set21rwe = set21ren & wren; // SET21R Write Enable
|
||||
assign set22rwe = set22ren & wren; // SET22R Write Enable
|
||||
assign set23rwe = set23ren & wren; // SET23R Write Enable
|
||||
assign set24rwe = set24ren & wren; // SET24R Write Enable
|
||||
assign set25rwe = set25ren & wren; // SET25R Write Enable
|
||||
assign set26rwe = set26ren & wren; // SET26R Write Enable
|
||||
assign set27rwe = set27ren & wren; // SET27R Write Enable
|
||||
assign set28rwe = set28ren & wren; // SET28R Write Enable
|
||||
assign set29rwe = set29ren & wren; // SET29R Write Enable
|
||||
assign set30rwe = set30ren & wren; // SET30R Write Enable
|
||||
assign set31rwe = set31ren & wren; // SET31R Write Enable
|
||||
assign casaddrrwe = casaddrren & wren; // CASADDRR Write Enable
|
||||
assign casdwrwe = casdwren & wren; // CASDWR Write Enable
|
||||
assign imctrwe = imctren & wren; // IMCTR Write Enable
|
||||
assign ibleedctrwe = ibleedctren & wren; // IBLEEDCTR Write Enable
|
||||
assign iclkcmlrwe = iclkcmlren & wren; // ICLKCMLR Write Enable
|
||||
assign currsvr0we = currsvr0en & wren; // CURRSVR0 Write Enable
|
||||
assign currsvr1we = currsvr1en & wren; // CURRSVR1 Write Enable
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- rtermr Register
|
||||
//
|
||||
// Write prbs_reg for 'RTERMR' : 4-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [3:0] --> rtermr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(4) rtermr_dfflrd (rtermrdft, rtermrwe, wrdata[3:0], rtermr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- prbsr Register
|
||||
//
|
||||
// Write prbs_reg for 'PRBSENR' : 1-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [0:0] --> prbsr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(1) prbsr_dfflrd (prbsrdft, prbsrwe, wrdata[0], prbsr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set0r Register
|
||||
//
|
||||
// Write set0r for 'SET0R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set0r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set0r_dfflrd (set0rdft, set0rwe, wrdata[31:0], set0r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set1r Register
|
||||
//
|
||||
// Write set1r for 'SET1R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set1r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set1r_dfflrd (set1rdft, set1rwe, wrdata[31:0], set1r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set2r Register
|
||||
//
|
||||
// Write set2r for 'SET2R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set2r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set2r_dfflrd (set2rdft, set2rwe, wrdata[31:0], set2r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set3r Register
|
||||
//
|
||||
// Write set3r for 'SET3R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set3r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set3r_dfflrd (set3rdft, set3rwe, wrdata[31:0], set3r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set4r Register
|
||||
//
|
||||
// Write set4r for 'SET4R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set4r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set4r_dfflrd (set4rdft, set4rwe, wrdata[31:0], set4r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set5r Register
|
||||
//
|
||||
// Write set5r for 'SET5R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set5r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set5r_dfflrd (set5rdft, set5rwe, wrdata[31:0], set5r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set6r Register
|
||||
//
|
||||
// Write set6r for 'SET6R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set6r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set6r_dfflrd (set6rdft, set6rwe, wrdata[31:0], set6r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set7r Register
|
||||
//
|
||||
// Write set7r for 'SET7R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set7r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set7r_dfflrd (set7rdft, set7rwe, wrdata[31:0], set7r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set8r Register
|
||||
//
|
||||
// Write set8r for 'SET8R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set8r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set8r_dfflrd (set8rdft, set8rwe, wrdata[31:0], set8r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set9r Register
|
||||
//
|
||||
// Write set9r for 'SET9R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set9r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set9r_dfflrd (set9rdft, set9rwe, wrdata[31:0], set9r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set10r Register
|
||||
//
|
||||
// Write set10r for 'SET10R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set10r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set10r_dfflrd (set10rdft, set10rwe, wrdata[31:0], set10r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set11r Register
|
||||
//
|
||||
// Write set11r for 'SET11R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set11r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set11r_dfflrd (set11rdft, set11rwe, wrdata[31:0], set11r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set12r Register
|
||||
//
|
||||
// Write set12r for 'SET12R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set12r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set12r_dfflrd (set12rdft, set12rwe, wrdata[31:0], set12r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set13r Register
|
||||
//
|
||||
// Write set13r for 'SET13R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set13r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set13r_dfflrd (set13rdft, set13rwe, wrdata[31:0], set13r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set14r Register
|
||||
//
|
||||
// Write set14r for 'SET14R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set14r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set14r_dfflrd (set14rdft, set14rwe, wrdata[31:0], set14r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set15r Register
|
||||
//
|
||||
// Write set15r for 'SET15R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set15r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set15r_dfflrd (set15rdft, set15rwe, wrdata[31:0], set15r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set16r Register
|
||||
//
|
||||
// Write set16r for 'SET16R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set16r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set16r_dfflrd (set16rdft, set16rwe, wrdata[31:0], set16r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set17r Register
|
||||
//
|
||||
// Write set17r for 'SET17R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set17r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set17r_dfflrd (set17rdft, set17rwe, wrdata[31:0], set17r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set18r Register
|
||||
//
|
||||
// Write set18r for 'SET18R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set18r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set18r_dfflrd (set18rdft, set18rwe, wrdata[31:0], set18r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set19r Register
|
||||
//
|
||||
// Write set19r for 'SET19R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set19r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set19r_dfflrd (set19rdft, set19rwe, wrdata[31:0], set19r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set20r Register
|
||||
//
|
||||
// Write set20r for 'SET20R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set20r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set20r_dfflrd (set20rdft, set20rwe, wrdata[31:0], set20r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set21r Register
|
||||
//
|
||||
// Write set21r for 'SET21R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set21r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set21r_dfflrd (set21rdft, set21rwe, wrdata[31:0], set21r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set22r Register
|
||||
//
|
||||
// Write set22r for 'SET22R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set22r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set22r_dfflrd (set22rdft, set22rwe, wrdata[31:0], set22r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set23r Register
|
||||
//
|
||||
// Write set23r for 'SET23R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set23r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set23r_dfflrd (set23rdft, set23rwe, wrdata[31:0], set23r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set24r Register
|
||||
//
|
||||
// Write set24r for 'SET24R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set24r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set24r_dfflrd (set24rdft, set24rwe, wrdata[31:0], set24r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set25r Register
|
||||
//
|
||||
// Write set25r for 'SET25R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set25r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set25r_dfflrd (set25rdft, set25rwe, wrdata[31:0], set25r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set26r Register
|
||||
//
|
||||
// Write set26r for 'SET26R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set26r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set26r_dfflrd (set26rdft, set26rwe, wrdata[31:0], set26r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set27r Register
|
||||
//
|
||||
// Write set27r for 'SET0R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set27r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set27r_dfflrd (set27rdft, set27rwe, wrdata[31:0], set27r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set28r Register
|
||||
//
|
||||
// Write set28r for 'SET0R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set28r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set28r_dfflrd (set28rdft, set28rwe, wrdata[31:0], set28r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set29r Register
|
||||
//
|
||||
// Write set29r for 'SET29R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set29r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set29r_dfflrd (set29rdft, set29rwe, wrdata[31:0], set29r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set30r Register
|
||||
//
|
||||
// Write set30r for 'SET30R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set30r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set30r_dfflrd (set30rdft, set30rwe, wrdata[31:0], set30r, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- set31r Register
|
||||
//
|
||||
// Write set31r for 'SET31R' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> set31r
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) set31r_dfflrd (set31rdft, set31rwe, wrdata[31:0], set31r, clk, rstn);
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- casaddrr Register
|
||||
//
|
||||
// Write casaddrr for 'CASADDRR' : 3-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [2:0] --> casaddrr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(3) casaddrr_dfflrd (casaddrrdft, casaddrrwe, wrdata[2:0], casaddrr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- casdwr Register
|
||||
//
|
||||
// Write casdwr for 'CASDWR' : 3-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [2:0] --> casdwr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(3) casdwr_dfflrd (casdwrdft, casdwrwe, wrdata[2:0], casdwr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- imctr Register
|
||||
//
|
||||
// Write imctr for 'IMCTR' : 10-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [9:0] --> imctr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(10) imctr_dfflrd (imctrdft, imctrwe, wrdata[9:0], imctr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- ibleedctr Register
|
||||
//
|
||||
// Write ibleedctr for 'IBLEEDCTR' : 4-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [3:0] --> ibleedctr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(4) ibleedctr_dfflrd (ibleedctrdft, ibleedctrwe, wrdata[3:0], ibleedctr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- iclkcmlr Register
|
||||
//
|
||||
// Write iclkcmlr for 'ICLKCMLR' : 4-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [3:0] --> iclkcmlr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(4) iclkcmlr_dfflrd (iclkcmlrdft, iclkcmlrwe, wrdata[3:0], iclkcmlr, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- currsvr0 Register
|
||||
//
|
||||
// Write currsvr0 for 'CURRSVR0' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> currsvr0
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) currsvr0_dfflrd (currsvr0dft, currsvr0we, wrdata[31:0], currsvr0, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- currsvr1 Register
|
||||
//
|
||||
// Write currsvr1 for 'CURRSVR1' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> currsvr1
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) currsvr1_dfflrd (currsvr1dft, currsvr1we, wrdata[31:0], currsvr1, clk, rstn);
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Read data mux
|
||||
//
|
||||
// -- The data from the selected register is
|
||||
// -- placed on a zero-padded 32-bit read data bus.
|
||||
// ------------------------------------------------------
|
||||
always @(*) begin : RDDATA_PROC
|
||||
rddata_reg = {32{1'b0}};
|
||||
if(rtermren == H ) rddata_reg[3 :0] = rtermr[3 :0] ;
|
||||
if(prbsren == H ) rddata_reg[0 :0] = prbsr[0 :0] ;
|
||||
if(set0ren == H ) rddata_reg[31:0] = set0r[31:0] ;
|
||||
if(set1ren == H ) rddata_reg[31:0] = set1r[31:0] ;
|
||||
if(set2ren == H ) rddata_reg[31:0] = set2r[31:0] ;
|
||||
if(set3ren == H ) rddata_reg[31:0] = set3r[31:0] ;
|
||||
if(set4ren == H ) rddata_reg[31:0] = set4r[31:0] ;
|
||||
if(set5ren == H ) rddata_reg[31:0] = set5r[31:0] ;
|
||||
if(set6ren == H ) rddata_reg[31:0] = set6r[31:0] ;
|
||||
if(set7ren == H ) rddata_reg[31:0] = set7r[31:0] ;
|
||||
if(set8ren == H ) rddata_reg[31:0] = set8r[31:0] ;
|
||||
if(set9ren == H ) rddata_reg[31:0] = set9r[31:0] ;
|
||||
if(set10ren == H ) rddata_reg[31:0] = set10r[31:0] ;
|
||||
if(set11ren == H ) rddata_reg[31:0] = set11r[31:0] ;
|
||||
if(set12ren == H ) rddata_reg[31:0] = set12r[31:0] ;
|
||||
if(set13ren == H ) rddata_reg[31:0] = set13r[31:0] ;
|
||||
if(set14ren == H ) rddata_reg[31:0] = set14r[31:0] ;
|
||||
if(set15ren == H ) rddata_reg[31:0] = set15r[31:0] ;
|
||||
if(set16ren == H ) rddata_reg[31:0] = set16r[31:0] ;
|
||||
if(set17ren == H ) rddata_reg[31:0] = set17r[31:0] ;
|
||||
if(set18ren == H ) rddata_reg[31:0] = set18r[31:0] ;
|
||||
if(set19ren == H ) rddata_reg[31:0] = set19r[31:0] ;
|
||||
if(set20ren == H ) rddata_reg[31:0] = set20r[31:0] ;
|
||||
if(set21ren == H ) rddata_reg[31:0] = set21r[31:0] ;
|
||||
if(set22ren == H ) rddata_reg[31:0] = set22r[31:0] ;
|
||||
if(set23ren == H ) rddata_reg[31:0] = set23r[31:0] ;
|
||||
if(set24ren == H ) rddata_reg[31:0] = set24r[31:0] ;
|
||||
if(set25ren == H ) rddata_reg[31:0] = set25r[31:0] ;
|
||||
if(set26ren == H ) rddata_reg[31:0] = set26r[31:0] ;
|
||||
if(set27ren == H ) rddata_reg[31:0] = set27r[31:0] ;
|
||||
if(set28ren == H ) rddata_reg[31:0] = set28r[31:0] ;
|
||||
if(set29ren == H ) rddata_reg[31:0] = set29r[31:0] ;
|
||||
if(set30ren == H ) rddata_reg[31:0] = set30r[31:0] ;
|
||||
if(set31ren == H ) rddata_reg[31:0] = set31r[31:0] ;
|
||||
if(casaddrren == H ) rddata_reg[2 :0] = casaddrr[2 :0] ;
|
||||
if(casdwren == H ) rddata_reg[2 :0] = casdwr[2 :0] ;
|
||||
if(imctren == H ) rddata_reg[9 :0] = imctr[9 :0] ;
|
||||
if(ibleedctren == H ) rddata_reg[3 :0] = ibleedctr[3 :0] ;
|
||||
if(iclkcmlren == H ) rddata_reg[3 :0] = iclkcmlr[3 :0] ;
|
||||
if(currsvr0en == H ) rddata_reg[31:0] = currsvr0[31:0] ;
|
||||
if(currsvr1en == H ) rddata_reg[31:0] = currsvr1[31:0] ;
|
||||
if(verren == H ) rddata_reg[31:0] = DACVERSION ;
|
||||
end
|
||||
|
||||
//rddata
|
||||
sirv_gnrl_dffr #(32) rddata_dffr (rddata_reg, rddata, clk, rstn);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Output signals assignment
|
||||
// ------------------------------------------------------
|
||||
assign Rterm = rtermr ; // R_Terminate
|
||||
assign PrbsEn = prbsr ; // Prbs_en
|
||||
assign Set[0] = set0r[14: 0] ;
|
||||
assign Set[1] = set0r[30:16] ;
|
||||
assign Set[2] = set1r[14: 0] ;
|
||||
assign Set[3] = set1r[30:16] ;
|
||||
assign Set[4] = set2r[14: 0] ;
|
||||
assign Set[5] = set2r[30:16] ;
|
||||
assign Set[6] = set3r[14: 0] ;
|
||||
assign Set[7] = set3r[30:16] ;
|
||||
assign Set[8] = set4r[14: 0] ;
|
||||
assign Set[9] = set4r[30:16] ;
|
||||
assign Set[10] = set5r[14: 0] ;
|
||||
assign Set[11] = set5r[30:16] ;
|
||||
assign Set[12] = set6r[14: 0] ;
|
||||
assign Set[13] = set6r[30:16] ;
|
||||
assign Set[14] = set7r[14: 0] ;
|
||||
assign Set[15] = set7r[30:16] ;
|
||||
assign Set[16] = set8r[14: 0] ;
|
||||
assign Set[17] = set8r[30:16] ;
|
||||
assign Set[18] = set9r[14: 0] ;
|
||||
assign Set[19] = set9r[30:16] ;
|
||||
assign Set[20] = set10r[14: 0] ;
|
||||
assign Set[21] = set10r[30:16] ;
|
||||
assign Set[22] = set11r[14: 0] ;
|
||||
assign Set[23] = set11r[30:16] ;
|
||||
assign Set[24] = set12r[14: 0] ;
|
||||
assign Set[25] = set12r[30:16] ;
|
||||
assign Set[26] = set13r[14: 0] ;
|
||||
assign Set[27] = set13r[30:16] ;
|
||||
assign Set[28] = set14r[14: 0] ;
|
||||
assign Set[29] = set14r[30:16] ;
|
||||
assign Set[30] = set15r[14: 0] ;
|
||||
assign Set[31] = set15r[30:16] ;
|
||||
assign Set[32] = set16r[14: 0] ;
|
||||
assign Set[33] = set16r[30:16] ;
|
||||
assign Set[34] = set17r[14: 0] ;
|
||||
assign Set[35] = set17r[30:16] ;
|
||||
assign Set[36] = set18r[14: 0] ;
|
||||
assign Set[37] = set18r[30:16] ;
|
||||
assign Set[38] = set19r[14: 0] ;
|
||||
assign Set[39] = set19r[30:16] ;
|
||||
assign Set[40] = set20r[14: 0] ;
|
||||
assign Set[41] = set20r[30:16] ;
|
||||
assign Set[42] = set21r[14: 0] ;
|
||||
assign Set[43] = set21r[30:16] ;
|
||||
assign Set[44] = set22r[14: 0] ;
|
||||
assign Set[45] = set22r[30:16] ;
|
||||
assign Set[46] = set23r[14: 0] ;
|
||||
assign Set[47] = set23r[30:16] ;
|
||||
assign Set[48] = set24r[14: 0] ;
|
||||
assign Set[49] = set24r[30:16] ;
|
||||
assign Set[50] = set25r[14: 0] ;
|
||||
assign Set[51] = set25r[30:16] ;
|
||||
assign Set[52] = set26r[14: 0] ;
|
||||
assign Set[53] = set26r[30:16] ;
|
||||
assign Set[54] = set27r[14: 0] ;
|
||||
assign Set[55] = set27r[30:16] ;
|
||||
assign Set[56] = set28r[14: 0] ;
|
||||
assign Set[57] = set28r[30:16] ;
|
||||
assign Set[58] = set29r[14: 0] ;
|
||||
assign Set[59] = set29r[30:16] ;
|
||||
assign Set[60] = set30r[14: 0] ;
|
||||
assign Set[61] = set30r[30:16] ;
|
||||
assign Set[62] = set31r[14: 0] ;
|
||||
assign Set[63] = set31r[30:16] ;
|
||||
|
||||
|
||||
assign CasAddr = casaddrr ;
|
||||
assign CasDw = casdwr ;
|
||||
assign IMainCtrl = imctr ;
|
||||
assign IBleedCtrl = ibleedctr ;
|
||||
assign ICkCml = iclkcmlr ;
|
||||
assign CurRsv0 = currsvr0 ;
|
||||
assign CurRsv1 = currsvr1 ;
|
||||
|
||||
endmodule
|
||||
|
||||
`undef RTERMR
|
||||
`undef PRBSENR
|
||||
`undef SET0R
|
||||
`undef SET1R
|
||||
`undef SET2R
|
||||
`undef SET3R
|
||||
`undef SET4R
|
||||
`undef SET5R
|
||||
`undef SET6R
|
||||
`undef SET7R
|
||||
`undef SET8R
|
||||
`undef SET9R
|
||||
`undef SET10R
|
||||
`undef SET11R
|
||||
`undef SET12R
|
||||
`undef SET13R
|
||||
`undef SET14R
|
||||
`undef SET15R
|
||||
`undef SET16R
|
||||
`undef SET17R
|
||||
`undef SET18R
|
||||
`undef SET19R
|
||||
`undef SET20R
|
||||
`undef SET21R
|
||||
`undef SET22R
|
||||
`undef SET23R
|
||||
`undef SET24R
|
||||
`undef SET25R
|
||||
`undef SET26R
|
||||
`undef SET27R
|
||||
`undef SET28R
|
||||
`undef SET29R
|
||||
`undef SET30R
|
||||
`undef SET31R
|
||||
`undef CASADDRR
|
||||
`undef CASDWR
|
||||
`undef IMCTR
|
||||
`undef IBLEEDCTR
|
||||
`undef ICLKCMLR
|
||||
`undef CURRSVR0
|
||||
`undef CURRSVR1
|
||||
`undef VERSIONR
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
//+FHDR--------------------------------------------------------------------------------------------------------
|
||||
// Company:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// File Name : dacif.v
|
||||
// Department :
|
||||
// Author : PWY
|
||||
// Author's Tel :
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Relese History
|
||||
// Version Date Author Description
|
||||
// 0.4 2024-03-12 PWY
|
||||
// 0.9 2024-06-19 PWY Add 2x, 4x, and 8x interpolation modes to EZQ2.0S.
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Keywords :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Parameter
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Target Device:
|
||||
// Tool versions:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Reuse Issues
|
||||
// Reset Strategy:
|
||||
// Clock Domains:
|
||||
// Critical Timing:
|
||||
// Asynchronous I/F:
|
||||
// Synthesizable (y/n):
|
||||
// Other:
|
||||
//-FHDR--------------------------------------------------------------------------------------------------------
|
||||
|
||||
module dacif (
|
||||
input clk
|
||||
,input rstn
|
||||
,input din_vld
|
||||
,output dout_vld
|
||||
//mixer data input
|
||||
,input [7:0] din [63:0]
|
||||
//data output
|
||||
,output [7:0] dout[63:0]
|
||||
);
|
||||
|
||||
wire[1 :0] dacif_vld_dly;
|
||||
sirv_gnrl_dffr #(2) dacif_vld_dffr ({dacif_vld_dly[0], din_vld}, dacif_vld_dly, clk, rstn);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// regs
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
wire[7:0] mux_p [63:0];
|
||||
|
||||
wire[7:0] dout_w [63:0];
|
||||
|
||||
genvar k;
|
||||
generate
|
||||
|
||||
for(k = 0; k < 64; k = k + 1) begin
|
||||
|
||||
sirv_gnrl_dfflr #(8) mux_dfflr (1'b1, {~din[k][7], din[k][6:0]}, mux_p[k], clk, rstn);
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
genvar m;
|
||||
generate
|
||||
////////////////////////////////////////////////////
|
||||
// mode select
|
||||
////////////////////////////////////////////////////
|
||||
for(m = 0; m < 64; m = m + 1) begin
|
||||
|
||||
assign dout_w[m] = mux_p [m] ;
|
||||
sirv_gnrl_dfflrd #(8) dout_dfflrd (8'h80, 1'b1, dout_w[m], dout[m], clk, rstn);
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign dout_vld = dacif_vld_dly[1];
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
//Defining Memory Types
|
||||
|
||||
//`define BEHAVIOR_SIM
|
||||
//`define XILINX_FPGA
|
||||
`define TSMC_IC
|
||||
|
||||
//Setting the Number of SPI Slave Devices
|
||||
`define SLVNUM 4
|
||||
//Whether SPI Bus Commands Are Buffered
|
||||
`define SPIBUS_CMD_REG 1
|
||||
//Whether SPI Bus Readout Are Buffered
|
||||
`define SPIBUS_OUT_REG 0
|
||||
//Whether Mod mux dout Are Buffered
|
||||
//`define MODDOUT_MUX_REG
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
//`undef BEHAVIOR_SIM
|
||||
//`undef XILINX_FPGA
|
||||
`undef TSMC_IC
|
||||
//Is the chip a 4-channel one?
|
||||
//`undef CHANNEL_IS_FOUR
|
||||
|
||||
//Setting the Number of SPI Slave Devices
|
||||
`undef SLVNUM
|
||||
//Whether SPI Bus Commands Are Buffered
|
||||
`undef SPIBUS_CMD_REG
|
||||
//Whether SPI Bus Readout Are Buffered
|
||||
`undef SPIBUS_OUT_REG
|
||||
|
||||
//Whether Mod mux dout Are Buffered
|
||||
//`undef MODDOUT_MUX_REG
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
module DA4008_DEM_Parallel_PRBS_1CH ( clk,
|
||||
data_in,
|
||||
prbs_en,
|
||||
set,
|
||||
MSB_DUM_IN,
|
||||
DEM_LSB_OUT,
|
||||
DEM_MSB_OUT,
|
||||
DEM_MSB_DUM
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
input clk, prbs_en;
|
||||
input [7:0] data_in;
|
||||
input [14:0] set;
|
||||
input MSB_DUM_IN;
|
||||
output [4:0] DEM_LSB_OUT;
|
||||
output [6:0] DEM_MSB_OUT;
|
||||
output DEM_MSB_DUM;
|
||||
|
||||
|
||||
reg [14:0]r_shift_data;
|
||||
|
||||
always @(posedge clk or negedge prbs_en)
|
||||
begin
|
||||
if(!prbs_en)
|
||||
|
||||
r_shift_data <=set;
|
||||
|
||||
else
|
||||
|
||||
begin
|
||||
|
||||
r_shift_data[0] <=r_shift_data[3];
|
||||
|
||||
r_shift_data[1] <= r_shift_data[4];
|
||||
|
||||
r_shift_data[2] <= r_shift_data[5];
|
||||
|
||||
r_shift_data[3] <= r_shift_data[6];
|
||||
|
||||
r_shift_data[4] <= r_shift_data[7];
|
||||
|
||||
r_shift_data[5] <= r_shift_data[8];
|
||||
|
||||
r_shift_data[6] <= r_shift_data[9];
|
||||
|
||||
r_shift_data[7] <= r_shift_data[10];
|
||||
|
||||
r_shift_data[8] <= r_shift_data[11];
|
||||
|
||||
r_shift_data[9] <= r_shift_data[12];
|
||||
|
||||
r_shift_data[10] <= r_shift_data[13];
|
||||
|
||||
r_shift_data[11] <= r_shift_data[14];
|
||||
|
||||
r_shift_data[12] <= r_shift_data[0]^r_shift_data[1];
|
||||
|
||||
r_shift_data[13] <= r_shift_data[2]^r_shift_data[1];
|
||||
|
||||
r_shift_data[14] <= r_shift_data[3]^r_shift_data[2];
|
||||
end
|
||||
end
|
||||
|
||||
wire [2:0]dd;
|
||||
|
||||
assign dd = {r_shift_data[0],r_shift_data[1], r_shift_data[2]};
|
||||
|
||||
reg [6:0] r_MSB_BUF0;
|
||||
|
||||
always @(posedge clk)
|
||||
|
||||
begin
|
||||
|
||||
case(dd[2:0])
|
||||
|
||||
3'd0: r_MSB_BUF0 <= {data_in[7],data_in[7],data_in[7],data_in[7],data_in[6],data_in[6],data_in[5]};
|
||||
|
||||
3'd1: r_MSB_BUF0 <= {data_in[7],data_in[7],data_in[7],data_in[6],data_in[6],data_in[5],data_in[7]};
|
||||
|
||||
3'd2: r_MSB_BUF0 <= {data_in[7],data_in[7],data_in[6],data_in[6],data_in[5],data_in[7],data_in[7]};
|
||||
|
||||
3'd3: r_MSB_BUF0 <= {data_in[7],data_in[6],data_in[6],data_in[5],data_in[7],data_in[7],data_in[7]};
|
||||
|
||||
3'd4: r_MSB_BUF0 <= {data_in[6],data_in[6],data_in[5],data_in[7],data_in[7],data_in[7],data_in[7]};
|
||||
|
||||
3'd5: r_MSB_BUF0 <= {data_in[6],data_in[5],data_in[7],data_in[7],data_in[7],data_in[7],data_in[6]};
|
||||
|
||||
3'd6: r_MSB_BUF0 <= {data_in[5],data_in[7],data_in[7],data_in[7],data_in[7],data_in[6],data_in[6]};
|
||||
|
||||
3'd7: r_MSB_BUF0 <= {data_in[7],data_in[7],data_in[7],data_in[7],data_in[6],data_in[6],data_in[5]};
|
||||
|
||||
endcase
|
||||
|
||||
end
|
||||
|
||||
reg [4:0] r_LSB_BUF0;
|
||||
reg r_DUM_BUF;
|
||||
|
||||
always @(posedge clk)
|
||||
|
||||
begin
|
||||
|
||||
r_LSB_BUF0 <= {data_in[4],data_in[3],data_in[2],data_in[1],data_in[0]};
|
||||
r_DUM_BUF <= MSB_DUM_IN;
|
||||
|
||||
end
|
||||
|
||||
assign DEM_LSB_OUT = r_LSB_BUF0;
|
||||
assign DEM_MSB_DUM = r_DUM_BUF;
|
||||
assign DEM_MSB_OUT = r_MSB_BUF0;
|
||||
|
||||
|
||||
endmodule
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,203 @@
|
|||
|
||||
////////////////////////////////////////////////
|
||||
//Engineer: Xiaodong Zhong
|
||||
//Date: 2019.5.21
|
||||
//Description: ?????ram
|
||||
////////////////////////////////////////////////
|
||||
module syn_fwft_fifo #(
|
||||
parameter width =16,
|
||||
parameter depth =1024,
|
||||
parameter prog_full_thre =512,
|
||||
parameter prog_empty_thre =16
|
||||
)(
|
||||
input clk,
|
||||
input rst,
|
||||
input clr,
|
||||
|
||||
input wr_en,
|
||||
input [width-1:0] din,
|
||||
output full,
|
||||
output almost_full,
|
||||
output prog_full,
|
||||
|
||||
|
||||
input rd_en,
|
||||
output [width-1:0] dout,
|
||||
output empty,
|
||||
output almost_empty,
|
||||
output prog_empty,
|
||||
|
||||
output [clog2(depth-1)-1:0] cnt
|
||||
);
|
||||
////////////////////////////////////////////////
|
||||
//log2 function
|
||||
////////////////////////////////////////////////
|
||||
function integer clog2(input integer depth);
|
||||
begin
|
||||
for(clog2=0;depth>0;clog2=clog2+1)
|
||||
depth =depth>>1;
|
||||
end
|
||||
endfunction
|
||||
|
||||
localparam aw = clog2(depth-1);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
//reg & wire
|
||||
////////////////////////////////////////////////
|
||||
reg [aw-1:0] wr_p;
|
||||
reg [aw-1:0] rd_p;
|
||||
wire [aw-1:0] rd_p_next;
|
||||
|
||||
reg [aw:0] i;
|
||||
reg wr_en_dly;
|
||||
|
||||
wire [width-1:0] ram_dout;
|
||||
wire ram_rden;
|
||||
////////////////////////////////////////////////
|
||||
//combinational logic
|
||||
////////////////////////////////////////////////
|
||||
//assign cnt = (wr_p >= rd_p) ? wr_p - rd_p : depth-rd_p+wr_p;
|
||||
|
||||
|
||||
assign full = (i>=(depth-1)) ? 1'b1 : 1'b0;
|
||||
assign almost_full = (i >=(depth-4)) ? 1'b1 : 1'b0;
|
||||
assign prog_full = (i >= (prog_full_thre-1)) ? 1'b1 :1'b0;
|
||||
|
||||
assign empty = (i==1'b0) ? 1'b1 : 1'b0;
|
||||
assign almost_empty = (i<=1'b1) ? 1'b1 : 1'b0;
|
||||
assign prog_empty = (i<=prog_empty_thre) ? 1'b1 :1'b0;
|
||||
|
||||
assign cnt = i[clog2(depth-1)-1:0];
|
||||
|
||||
assign rd_p_next = rd_p + {{(aw-2){1'b0}}, (rd_en & !empty)};
|
||||
////////////////////////////////////////////////
|
||||
//timing
|
||||
////////////////////////////////////////////////
|
||||
reg wr_clr_r;
|
||||
reg wr_clr;
|
||||
//----------------------------------------------
|
||||
always @(posedge clk or posedge clr)
|
||||
if(clr)
|
||||
wr_clr <= 1'b1;
|
||||
else if(!wr_clr_r)
|
||||
wr_clr <= 1'b0;// Release Clear
|
||||
|
||||
always @(posedge clk or posedge clr)
|
||||
if(clr)
|
||||
wr_clr_r <= 1'b1;
|
||||
else
|
||||
wr_clr_r <= 1'b0;
|
||||
//----------------------------------------------
|
||||
always@(posedge clk or posedge rst)begin
|
||||
if(rst )begin
|
||||
wr_en_dly <=1'b0;
|
||||
end
|
||||
else begin
|
||||
wr_en_dly <=wr_en;
|
||||
end
|
||||
end
|
||||
|
||||
always@(posedge clk or posedge rst)begin
|
||||
if(rst )begin
|
||||
wr_p <=0;
|
||||
end
|
||||
else if(wr_clr)begin
|
||||
wr_p <=0;
|
||||
end
|
||||
else if(wr_en)begin
|
||||
if(wr_p == depth-1)begin
|
||||
wr_p <=0;
|
||||
end
|
||||
else begin
|
||||
wr_p <=wr_p+1;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
wr_p <=wr_p;
|
||||
end
|
||||
end
|
||||
|
||||
//----------------------------------------------
|
||||
always@(posedge clk or posedge rst)begin
|
||||
if(rst )begin
|
||||
rd_p <=0;
|
||||
end
|
||||
else if(wr_clr)begin
|
||||
rd_p <=0;
|
||||
end
|
||||
else if(rd_en)begin
|
||||
if(rd_p == depth-1)begin
|
||||
rd_p <=0;
|
||||
end
|
||||
else begin
|
||||
rd_p <=rd_p+1;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
rd_p <=rd_p;
|
||||
end
|
||||
end
|
||||
|
||||
//----------------------------------------------
|
||||
always@(posedge clk or posedge rst)begin
|
||||
if(rst)begin
|
||||
i <=0;
|
||||
end
|
||||
else if(wr_clr)begin
|
||||
i <=0;
|
||||
end
|
||||
else begin
|
||||
case({wr_en_dly,rd_en})
|
||||
2'b00:begin
|
||||
i <=i;
|
||||
end
|
||||
2'b01:begin
|
||||
if(i!=0)begin
|
||||
i <=i-1'b1;
|
||||
end
|
||||
else begin
|
||||
i <=i;
|
||||
end
|
||||
end
|
||||
2'b10:begin
|
||||
if(i!=depth)begin
|
||||
i <=i+1'b1;
|
||||
end
|
||||
else begin
|
||||
i <=i;
|
||||
end
|
||||
end
|
||||
2'b11:begin
|
||||
i <=i;
|
||||
end
|
||||
default:begin
|
||||
i <=i;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
////////////////////////////////////////////////
|
||||
//SRAM
|
||||
////////////////////////////////////////////////
|
||||
spram #(
|
||||
.width (width ),
|
||||
.depth (depth )
|
||||
)spram(
|
||||
.clka (clk ),
|
||||
.ena (wr_en ),
|
||||
.dina (din ),
|
||||
.addra (wr_p ),
|
||||
|
||||
.clkb (clk ),
|
||||
//.enb (1'b1 ),
|
||||
.enb (ram_rden ),
|
||||
.doutb (ram_dout ),
|
||||
.addrb (rd_p_next )
|
||||
);
|
||||
|
||||
assign ram_rden = wr_p != rd_p_next;
|
||||
assign dout = empty ? 0 : ram_dout;
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
//+FHDR--------------------------------------------------------------------------------------------------------
|
||||
// Company:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// File Name : iopad.v
|
||||
// Department :
|
||||
// Author : pwy
|
||||
// Author's Tel :
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Relese History
|
||||
// Version Date Author Description
|
||||
// 1.2 2024-06-12 pwy Integrate a digital module and two SPI modules with PLL
|
||||
// 1.3 2024-11-12 pwy Adding an Attenuator Configuration Interface
|
||||
// 1.4 2025-08-14 pwy Modify IRQ output logic
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Keywords :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Parameter
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Target Device:
|
||||
// Tool versions:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Reuse Issues
|
||||
// Reset Strategy:
|
||||
// Clock Domains:
|
||||
// Critical Timing:
|
||||
// Asynchronous I/F:
|
||||
// Synthesizable (y/n):
|
||||
// Other:
|
||||
//-FHDR--------------------------------------------------------------------------------------------------------
|
||||
`include "../define/chip_define.v"
|
||||
module iopad (
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++//
|
||||
// PAD Strat //
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++//
|
||||
input PI_async_rstn // hardware Reset, active low
|
||||
//sync
|
||||
,input PI_sync_in // Chip synchronization signal input, high pulse valid
|
||||
,output PO_sync_out // Chip synchronization signal output, high pulse valid
|
||||
//spi port
|
||||
,input PI_sclk // Spi Clock
|
||||
,input PI_csn // Spi Chip Select active low
|
||||
,input PI_mosi // Spi Mosi
|
||||
,output PO_miso // Spi Miso
|
||||
//irq
|
||||
,output PO_irq // Interrupt signal in the chip, high level active
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++//
|
||||
// PAD End //
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++//
|
||||
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++//
|
||||
// Internal signal Start //
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++//
|
||||
,output async_rstn // hardware Reset, active low
|
||||
//sync
|
||||
,output sync_in // Chip synchronization signal to analog, high pulse valid
|
||||
,input sync_out // Chip synchronization signal output, high pulse valid
|
||||
//spi port
|
||||
,output sclk // Spi Clock
|
||||
,output csn // Spi Chip Select active low
|
||||
,output mosi // Spi Mosi
|
||||
,input miso // Spi Miso
|
||||
,input oen // Spi Miso output enable
|
||||
//irq
|
||||
,input irq_n // Interrupt signal in the chip, high level active
|
||||
);
|
||||
|
||||
`ifdef TSMC_IC
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++//
|
||||
// ASIC PAD --> TSMC //
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++//
|
||||
//PI_async_rstn,pull-up
|
||||
PDUW04SDGZ_V_G PDUW08SDGZ_V_G_async_rstn (
|
||||
.I ( 1'b0 )
|
||||
,.OEN ( 1'b1 )
|
||||
,.REN ( 1'b0 )
|
||||
,.PAD ( PI_async_rstn )
|
||||
,.C ( async_rstn )
|
||||
);
|
||||
|
||||
//sync_in,pull-down
|
||||
PDDW04SDGZ_V_G PDDW04SDGZ_V_G_sync_in (
|
||||
.I ( 1'b0 )
|
||||
,.OEN ( 1'b1 )
|
||||
,.REN ( 1'b0 )
|
||||
,.PAD ( PI_sync_in )
|
||||
,.C ( sync_in )
|
||||
);
|
||||
|
||||
//sync_out,pull-down
|
||||
PDDW04SDGZ_V_G PDDW08SDGZ_V_G_sync_out (
|
||||
.I ( sync_out )
|
||||
,.OEN ( 1'b0 )
|
||||
,.REN ( 1'b0 )
|
||||
,.PAD ( PO_sync_out )
|
||||
,.C ( )
|
||||
);
|
||||
|
||||
//sclk,pull-up
|
||||
PDUW04SDGZ_V_G PDUW04SDGZ_V_G_sclk (
|
||||
.I ( 1'b0 )
|
||||
,.OEN ( 1'b1 )
|
||||
,.REN ( 1'b0 )
|
||||
,.PAD ( PI_sclk )
|
||||
,.C ( sclk )
|
||||
);
|
||||
|
||||
//csn,pull-up
|
||||
PDUW04SDGZ_V_G PDUW04SDGZ_V_G_csn (
|
||||
.I ( 1'b0 )
|
||||
,.OEN ( 1'b1 )
|
||||
,.REN ( 1'b0 )
|
||||
,.PAD ( PI_csn )
|
||||
,.C ( csn )
|
||||
);
|
||||
|
||||
//mosi,pull-up
|
||||
PDUW08SDGZ_V_G PDUW08SDGZ_V_G_mosi (
|
||||
.I ( 1'b0 )
|
||||
,.OEN ( 1'b1 )
|
||||
,.REN ( 1'b0 )
|
||||
,.PAD ( PI_mosi )
|
||||
,.C ( mosi )
|
||||
);
|
||||
|
||||
//miso,pull-up
|
||||
PDUW08SDGZ_V_G PDUW08SDGZ_V_G_miso (
|
||||
.I ( miso )
|
||||
,.OEN ( oen )
|
||||
,.REN ( 1'b0 )
|
||||
,.PAD ( PO_miso )
|
||||
,.C ( )
|
||||
);
|
||||
|
||||
//irq,pull-up
|
||||
PDUW08SDGZ_V_G PDUW08SDGZ_V_G_irq (
|
||||
.I ( 1'b0 )
|
||||
,.OEN ( irq_n )
|
||||
,.REN ( 1'b0 )
|
||||
,.PAD ( PO_irq )
|
||||
,.C ( )
|
||||
);
|
||||
|
||||
|
||||
|
||||
`elsif XILINX_FPGA
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++//
|
||||
// FPGA PAD --> Xlinx //
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++//
|
||||
//async_rstn
|
||||
assign async_rstn = PI_async_rstn ;
|
||||
//sync_in
|
||||
assign sync_to_analog = PI_sync_in ;
|
||||
//sync_out
|
||||
assign PO_sync_out = sync_out ;
|
||||
//Feedback signal
|
||||
assign ch0_feedback = PI_ch0_feedback ;
|
||||
`ifdef CHANNEL_IS_FOUR
|
||||
assign ch1_feedback = PI_ch1_feedback ;
|
||||
assign ch2_feedback = PI_ch2_feedback ;
|
||||
assign ch3_feedback = PI_ch3_feedback ;
|
||||
`endif
|
||||
//config chip id
|
||||
assign cfgid = PI_cfgid ;
|
||||
//spi port
|
||||
assign sclk = PI_sclk ;
|
||||
assign csn = PI_csn ;
|
||||
assign mosi = PI_mosi ;
|
||||
assign PO_miso = oen ? 1'bz : miso ;
|
||||
//irq
|
||||
assign PO_irq = irq_n ;
|
||||
|
||||
`ifdef CHANNEL_IS_FOUR
|
||||
assign PO_ch0_att = ch0_att ;
|
||||
assign PO_ch1_att = ch1_att ;
|
||||
assign PO_ch2_att = ch2_att ;
|
||||
assign PO_ch3_att = ch3_att ;
|
||||
`endif
|
||||
|
||||
`endif
|
||||
|
||||
endmodule
|
||||
`include "../define/chip_undefine.v"
|
||||
|
|
@ -0,0 +1,765 @@
|
|||
// ============================================================================
|
||||
// Top Module: ulink_rx
|
||||
// Integrates training, descrambling, and frame reception, outputs 512-bit block writes to SRAM
|
||||
// ============================================================================
|
||||
module ulink_rx #(
|
||||
parameter FIFO_DEPTH = 64, // Input FIFO depth
|
||||
parameter [31:0] SCRAMBLER_SEED = 32'hFFFFFFFF // Fixed seed for descrambler (all lanes share)
|
||||
)(
|
||||
input logic clk
|
||||
,input logic rst_n // Active-low reset
|
||||
// 4-lane serial input
|
||||
,input logic [3 :0] serial_in
|
||||
// Training parameters
|
||||
,input logic [19 :0] patn_count
|
||||
,input logic [2 :0] tap_step
|
||||
,input logic [2 :0] tap_adj_mask // Delay adjustment mask
|
||||
,input logic [0 :0] tap_force // Delay force to tap_step
|
||||
,input logic force_train
|
||||
,input logic descram_en
|
||||
,input logic always_on
|
||||
,input logic prefilling
|
||||
,output logic prefill_start
|
||||
// Link status outputs
|
||||
,output logic link_down
|
||||
,output logic train_ready
|
||||
,output logic [2 :0] delay_tap
|
||||
,output logic tap_adj_req
|
||||
// SRAM write interface (each block is 512 bits)
|
||||
,output logic [12 :0] wr_addr
|
||||
,output logic [511:0] wr_data
|
||||
,output logic wr_en
|
||||
,output logic [63 :0] byte_mask
|
||||
// CRC error indication (can be used for external monitoring or to restart training)
|
||||
,output logic crc_error
|
||||
,output logic frame_done
|
||||
,output logic [31 :0] train_status
|
||||
,output logic [31 :0] frame_status
|
||||
);
|
||||
|
||||
// Internal connection signals
|
||||
//logic train_ready; // Training ready (not used, but can be exported)
|
||||
logic data_valid; // Data valid pulse from training module
|
||||
logic [127:0] data_int; // 128-bit data from training module
|
||||
logic [127:0] descrambled_data; // Descrambled data
|
||||
logic descrambled_valid; // Descrambled data valid
|
||||
logic [0 :0] train_en; // Training enable
|
||||
logic [3 :0] descram_valid;
|
||||
|
||||
// ========================================================================
|
||||
// prefill module instantiation
|
||||
// ========================================================================
|
||||
prefill #(
|
||||
.DELAY ( 20'd10000 )
|
||||
) U_prefill (
|
||||
.clk ( clk )
|
||||
,.rst_n ( rst_n )
|
||||
,.always_on ( always_on )
|
||||
,.prefilling ( prefilling )
|
||||
,.prefill_start ( prefill_start )
|
||||
,.prefill_done ( train_en )
|
||||
);
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// Training module instantiation
|
||||
// ========================================================================
|
||||
ulink_rx_train u_train (
|
||||
.clk ( clk )
|
||||
,.rst_n ( rst_n )
|
||||
,.serial_in ( serial_in )
|
||||
,.patn_count ( patn_count )
|
||||
,.frame_error ( crc_error ) // Frame error feedback to restart training
|
||||
,.frame_done ( frame_done )
|
||||
,.tap_step ( tap_step )
|
||||
,.tap_adj_mask ( tap_adj_mask )
|
||||
,.tap_force ( tap_force )
|
||||
,.force_train ( force_train )
|
||||
,.train_en ( train_en )
|
||||
,.link_down ( link_down )
|
||||
,.delay_tap ( delay_tap )
|
||||
,.tap_adj_req ( tap_adj_req )
|
||||
,.train_ready ( train_ready )
|
||||
,.descram_valid ( descram_valid )
|
||||
,.data_valid ( data_valid )
|
||||
,.data_out ( data_int )
|
||||
,.train_status ( train_status )
|
||||
);
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// Descrambler module instantiation (128-bit, all lanes share the same seed)
|
||||
// ========================================================================
|
||||
ulink_descrambler_128 #(
|
||||
.SEED ( SCRAMBLER_SEED )
|
||||
) u_descrambler (
|
||||
.clk ( clk )
|
||||
,.rst_n ( rst_n )
|
||||
,.data_in ( data_int )
|
||||
,.valid_in ( descram_valid )
|
||||
,.enable ( descram_en ) // Always enable descrambling
|
||||
,.data_out ( descrambled_data )
|
||||
,.valid_out ( descrambled_valid )
|
||||
);
|
||||
|
||||
// ========================================================================
|
||||
// Frame receiver module instantiation
|
||||
// ========================================================================
|
||||
ulink_frame_receiver #(
|
||||
.FIFO_DEPTH ( FIFO_DEPTH )
|
||||
) u_frame (
|
||||
.clk ( clk )
|
||||
,.rst_n ( rst_n )
|
||||
,.data_in ( descrambled_data )
|
||||
,.valid_in ( descrambled_valid )
|
||||
,.wr_addr ( wr_addr )
|
||||
,.wr_data ( wr_data )
|
||||
,.wr_en ( wr_en )
|
||||
,.byte_mask ( byte_mask )
|
||||
,.crc_error ( crc_error )
|
||||
,.frame_done ( frame_done )
|
||||
,.frame_status ( frame_status )
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// Sub-module definitions (can be placed in separate files as needed)
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// 32-bit Descrambler (used inside the 128-bit descrambler)
|
||||
// ----------------------------------------------------------------------------
|
||||
module ulink_descrambler_32 #(
|
||||
parameter [31:0] SEED = 32'hFFFFFFFF
|
||||
) (
|
||||
input logic clk
|
||||
,input logic rst_n
|
||||
,input logic [31:0] data_in
|
||||
,input logic valid_in
|
||||
,input logic enable
|
||||
,output logic [31:0] data_out
|
||||
,output logic valid_out
|
||||
);
|
||||
logic [31:0] lfsr, next_lfsr;
|
||||
wire feedback = lfsr[31] ^ lfsr[30] ^ lfsr[29] ^ lfsr[28];
|
||||
assign next_lfsr = {lfsr[30:0], feedback};
|
||||
|
||||
always_ff @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
lfsr <= SEED;
|
||||
else if (valid_in && enable)
|
||||
lfsr <= next_lfsr;
|
||||
end
|
||||
|
||||
logic [31:0] descrambled;
|
||||
assign descrambled = valid_in && enable ? (data_in ^ lfsr) : data_in;
|
||||
|
||||
always_ff @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
data_out <= 32'h0;
|
||||
valid_out <= 1'b0;
|
||||
end else begin
|
||||
data_out <= descrambled;
|
||||
valid_out <= valid_in;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// 128-bit Descrambler (composed of four 32-bit descramblers)
|
||||
// ----------------------------------------------------------------------------
|
||||
module ulink_descrambler_128 #(
|
||||
parameter [31:0] SEED = 32'hFFFFFFFF
|
||||
) (
|
||||
input logic clk
|
||||
,input logic rst_n
|
||||
,input logic [127:0] data_in
|
||||
,input logic [3 :0] valid_in
|
||||
,input logic enable
|
||||
,output logic [127:0] data_out
|
||||
,output logic valid_out
|
||||
);
|
||||
logic [31:0] lane0_out, lane1_out, lane2_out, lane3_out;
|
||||
logic valid_out0, valid_out1, valid_out2, valid_out3;
|
||||
|
||||
ulink_descrambler_32 #(.SEED(SEED)) u0 (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
.data_in (data_in[31:0]),
|
||||
.valid_in (valid_in[0]),
|
||||
.enable (enable),
|
||||
.data_out (lane0_out),
|
||||
.valid_out(valid_out0)
|
||||
);
|
||||
ulink_descrambler_32 #(.SEED(SEED)) u1 (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
.data_in (data_in[63:32]),
|
||||
.valid_in (valid_in[1]),
|
||||
.enable (enable),
|
||||
.data_out (lane1_out),
|
||||
.valid_out(valid_out1)
|
||||
);
|
||||
ulink_descrambler_32 #(.SEED(SEED)) u2 (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
.data_in (data_in[95:64]),
|
||||
.valid_in (valid_in[2]),
|
||||
.enable (enable),
|
||||
.data_out (lane2_out),
|
||||
.valid_out(valid_out2)
|
||||
);
|
||||
ulink_descrambler_32 #(.SEED(SEED)) u3 (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
.data_in (data_in[127:96]),
|
||||
.valid_in (valid_in[3]),
|
||||
.enable (enable),
|
||||
.data_out (lane3_out),
|
||||
.valid_out(valid_out3)
|
||||
);
|
||||
|
||||
assign data_out = {lane3_out, lane2_out, lane1_out, lane0_out};
|
||||
assign valid_out = valid_out1; // All lanes are synchronized
|
||||
endmodule
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// CRC32 Module (used in frame receiver)
|
||||
// ----------------------------------------------------------------------------
|
||||
module crc32 #(
|
||||
parameter POLY = 32'h04C11DB7
|
||||
,parameter INIT = 32'hFFFFFFFF
|
||||
)(
|
||||
input logic clk
|
||||
,input logic rst_n
|
||||
,input logic clear
|
||||
,input logic [31:0] data
|
||||
,input logic valid
|
||||
,output logic [31:0] crc
|
||||
);
|
||||
logic [31:0] crc_reg, crc_next;
|
||||
integer i;
|
||||
logic data_bit;
|
||||
|
||||
always_ff @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
crc_reg <= INIT;
|
||||
else if (clear)
|
||||
crc_reg <= INIT;
|
||||
else if (valid)
|
||||
crc_reg <= crc_next;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
crc_next = crc_reg;
|
||||
for (i = 0; i < 32; i++) begin
|
||||
data_bit = crc_next[31] ^ data[31-i];
|
||||
crc_next = {crc_next[30:0], 1'b0};
|
||||
if (data_bit) crc_next = crc_next ^ POLY;
|
||||
end
|
||||
end
|
||||
assign crc = crc_reg;
|
||||
endmodule
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Frame Receiver Module (uses syn_fwft_fifo)
|
||||
// ----------------------------------------------------------------------------
|
||||
module ulink_frame_receiver #(
|
||||
parameter FIFO_DEPTH = 64
|
||||
)(
|
||||
input logic clk
|
||||
,input logic rst_n
|
||||
,input logic [127:0] data_in
|
||||
,input logic valid_in
|
||||
,output logic [12:0] wr_addr
|
||||
,output logic [511:0] wr_data
|
||||
,output logic wr_en
|
||||
,output logic [63:0] byte_mask
|
||||
,output logic [31:0] frame_status
|
||||
,output logic crc_error
|
||||
,output logic frame_done
|
||||
);
|
||||
// Frame header constant
|
||||
localparam FRAME_HEADER = 32'hBCBCBCBC;
|
||||
|
||||
|
||||
|
||||
|
||||
// FIFO instantiation
|
||||
logic fifo_rd_en;
|
||||
logic [127:0] fifo_dout;
|
||||
logic fifo_empty;
|
||||
|
||||
//syn_fwft_fifo
|
||||
syn_fwft_fifo #(
|
||||
.width ( 128 )
|
||||
,.depth ( FIFO_DEPTH )
|
||||
) u_fifo (
|
||||
.clk ( clk )
|
||||
,.rst ( ~rst_n )
|
||||
,.clr ( 1'b0 )
|
||||
,.wr_en ( valid_in )
|
||||
,.din ( data_in )
|
||||
,.full ( )
|
||||
,.almost_full ( )
|
||||
,.prog_full ( )
|
||||
,.rd_en (fifo_rd_en )
|
||||
,.dout (fifo_dout )
|
||||
,.empty (fifo_empty )
|
||||
,.almost_empty ( )
|
||||
,.prog_empty ( )
|
||||
,.cnt ( )
|
||||
);
|
||||
|
||||
// Split 128-bit data into four 32-bit words
|
||||
typedef enum logic [2:0] { S_IDLE, S_WORD0, S_WORD1, S_WORD2, S_WORD3 } word_state_t;
|
||||
word_state_t word_state_c, word_state_n;
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- word state machine
|
||||
// ------------------------------------------------------
|
||||
|
||||
//jump conditions
|
||||
wire idle2word0 = (word_state_c == S_IDLE ) && !fifo_empty;
|
||||
wire word02word1 = (word_state_c == S_WORD0 ) ;
|
||||
wire word12word2 = (word_state_c == S_WORD1 ) ;
|
||||
wire word22word3 = (word_state_c == S_WORD2 ) ;
|
||||
wire word32idle = (word_state_c == S_WORD3 ) ;
|
||||
|
||||
|
||||
//state_n
|
||||
assign word_state_n = ((word_state_c == S_IDLE ) && idle2word0 ) ? S_WORD0 :
|
||||
((word_state_c == S_WORD0 ) && word02word1 ) ? S_WORD1 :
|
||||
((word_state_c == S_WORD1 ) && word12word2 ) ? S_WORD2 :
|
||||
((word_state_c == S_WORD2 ) && word22word3 ) ? S_WORD3 :
|
||||
((word_state_c == S_WORD3 ) && word32idle ) ? S_IDLE :
|
||||
word_state_c ;
|
||||
//word_state_c
|
||||
sirv_gnrl_edffr #(.T(word_state_t)) word_state_c_dffr (word_state_n,word_state_c,clk, rst_n);
|
||||
|
||||
|
||||
//fifo_rd_en
|
||||
assign fifo_rd_en = idle2word0;
|
||||
|
||||
wire [127:0] current_fifo_data;
|
||||
|
||||
sirv_gnrl_dfflr #(128) current_fifo_data_dfflr (fifo_rd_en, fifo_dout, current_fifo_data, clk, rst_n);
|
||||
|
||||
wire [31:0] current_word_w = (word_state_c == S_WORD0) ? current_fifo_data[31:0] :
|
||||
(word_state_c == S_WORD1) ? current_fifo_data[63:32] :
|
||||
(word_state_c == S_WORD2) ? current_fifo_data[95:64] :
|
||||
(word_state_c == S_WORD3) ? current_fifo_data[127:96] :
|
||||
32'h0;
|
||||
wire word_valid_w = (word_state_c != S_IDLE);
|
||||
|
||||
wire [31:0] current_word;
|
||||
|
||||
sirv_gnrl_dfflr #(32) current_word_dfflr (word_valid_w, current_word_w, current_word, clk, rst_n);
|
||||
|
||||
wire word_valid;
|
||||
|
||||
sirv_gnrl_dffr #(1) word_valid_dffr (word_valid_w, word_valid, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Frame parsing FSM
|
||||
// ------------------------------------------------------
|
||||
typedef enum logic [2:0] { ST_IDLE, ST_HEAD, ST_DATA, ST_CRC } state_t;
|
||||
state_t state_c, state_n;
|
||||
|
||||
//data_len
|
||||
wire [15:0] data_len;
|
||||
sirv_gnrl_dfflr #(16) data_len_dfflr ((state_c == ST_HEAD ), current_word[15:0], data_len, clk, rst_n);
|
||||
//data_cnt contrl
|
||||
wire [15:0] data_cnt;
|
||||
wire add_data_cnt = (state_c == ST_DATA ) && word_valid;
|
||||
wire end_data_cnt = add_data_cnt && (state_c == ST_DATA ) && (data_cnt == data_len -1);
|
||||
|
||||
wire [15:0] data_cnt_n = end_data_cnt ? 5'h0 :
|
||||
add_data_cnt ? data_cnt + 1'b1 :
|
||||
data_cnt ;
|
||||
|
||||
sirv_gnrl_dffr #(16) data_cnt_dffr (data_cnt_n, data_cnt, clk, rst_n);
|
||||
|
||||
|
||||
//jump conditions
|
||||
wire idle2head = (state_c == ST_IDLE ) && (word_valid && current_word == FRAME_HEADER);
|
||||
wire head2data = (state_c == ST_HEAD ) && word_valid;
|
||||
wire data2crc = (state_c == ST_DATA ) && end_data_cnt;
|
||||
wire crc2idle = (state_c == ST_CRC ) && word_valid;
|
||||
|
||||
//state_n
|
||||
assign state_n = ((state_c == ST_IDLE ) && idle2head ) ? ST_HEAD :
|
||||
((state_c == ST_HEAD ) && head2data ) ? ST_DATA :
|
||||
((state_c == ST_DATA ) && data2crc ) ? ST_CRC :
|
||||
((state_c == ST_CRC ) && crc2idle ) ? ST_IDLE :
|
||||
state_c ;
|
||||
//state_c
|
||||
sirv_gnrl_edffr #(.T(state_t)) state_c_dffr (state_n,state_c,clk, rst_n);
|
||||
|
||||
|
||||
//cur_block_offset
|
||||
wire [3:0] cur_block_offset;
|
||||
|
||||
wire add_cur_block_offset = (state_c == ST_DATA ) && word_valid;
|
||||
wire end_cur_block_offset = (state_c == ST_DATA ) && add_cur_block_offset && (cur_block_offset == 16-1);;
|
||||
|
||||
wire [3:0] cur_block_offset_n = end_cur_block_offset ? 5'h0 :
|
||||
(state_c == ST_HEAD ) ? current_word[19:16] :
|
||||
add_cur_block_offset ? cur_block_offset + 1'b1 :
|
||||
cur_block_offset ;
|
||||
|
||||
sirv_gnrl_dffr #(4) cur_block_offset_dffr (cur_block_offset_n, cur_block_offset, clk, rst_n);
|
||||
|
||||
//block_done
|
||||
wire block_done;
|
||||
|
||||
sirv_gnrl_dffr #(1) block_done_dffr ((state_c == ST_DATA) && ((end_data_cnt && !end_cur_block_offset) || end_cur_block_offset), block_done, clk, rst_n);
|
||||
|
||||
//base_addr
|
||||
wire [15:0] base_addr;
|
||||
sirv_gnrl_dfflr #(16) base_addr_dfflr ((state_c == ST_HEAD ), current_word[31:16], base_addr, clk, rst_n);
|
||||
|
||||
//cur_block_addr
|
||||
wire [12:0] cur_block_addr;
|
||||
wire [12:0] cur_block_addr_w = end_cur_block_offset ? cur_block_addr + 1'b1 :
|
||||
(state_c == ST_HEAD) ? current_word[31:16] >> 4 :
|
||||
crc2idle ? 13'd0 :
|
||||
cur_block_addr;
|
||||
|
||||
sirv_gnrl_dffr #(13) cur_block_addr_dffr (cur_block_addr_w, cur_block_addr, clk, rst_n);
|
||||
|
||||
//cur_block_data
|
||||
wire [31:0] cur_block_data [15:0];
|
||||
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < 16; i++) begin : gen_block_data
|
||||
wire load_sel = (state_c == ST_DATA) && (cur_block_offset == i);
|
||||
sirv_gnrl_dfflr #(32) cur_block_data_dfflr (load_sel, current_word, cur_block_data[i], clk, rst_n);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
//cur_block_mask
|
||||
wire [63:0] cur_block_mask;
|
||||
|
||||
wire clear_mask = (state_c == ST_HEAD) || block_done;
|
||||
|
||||
genvar j;
|
||||
generate
|
||||
for (j = 0; j < 16; j++) begin : gen_mask
|
||||
wire load_sel_mask = (state_c == ST_DATA) && (cur_block_offset == j);
|
||||
wire load_en = load_sel_mask || clear_mask;
|
||||
wire [3:0] dnxt = load_sel_mask ? 4'b1111 :
|
||||
clear_mask ? 4'b0000 :
|
||||
4'b1111;
|
||||
sirv_gnrl_dfflr #(4) cur_block_mask_dfflr (load_en, dnxt, cur_block_mask[j*4 +: 4], clk, rst_n);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
|
||||
//SRAM Write Ouput Contrl
|
||||
|
||||
//wr_addr
|
||||
wire [12:0] cur_block_addr_r;
|
||||
sirv_gnrl_dffr #(13) cur_block_addr_r_dffr (cur_block_addr, cur_block_addr_r, clk, rst_n);
|
||||
sirv_gnrl_dfflr #(13) wr_addr_dfflr (block_done, cur_block_addr_r, wr_addr, clk, rst_n);
|
||||
|
||||
//wr_data
|
||||
wire [511:0] cur_block_data_packed;
|
||||
genvar k;
|
||||
generate
|
||||
for (k = 0; k < 16; k++) begin : pack_cur_block_data
|
||||
assign cur_block_data_packed[32*k +: 32] = cur_block_data[k];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
sirv_gnrl_dfflr #(512) wr_data_dfflr (block_done, cur_block_data_packed, wr_data, clk, rst_n);
|
||||
|
||||
|
||||
//byte_mask
|
||||
sirv_gnrl_dfflr #(64) byte_mask_dfflr (block_done, cur_block_mask, byte_mask, clk, rst_n);
|
||||
|
||||
//wr_en
|
||||
sirv_gnrl_dffr #(1) wr_en_dffr (block_done, wr_en, clk, rst_n);
|
||||
|
||||
//frame_done
|
||||
sirv_gnrl_dffr #(1) frame_done_dffr (crc2idle, frame_done, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- CRC32 instance
|
||||
// ------------------------------------------------------
|
||||
wire crc_clear, crc_valid;
|
||||
wire [31:0] crc_out;
|
||||
crc32 u_crc32 (
|
||||
.clk ( clk )
|
||||
,.rst_n ( rst_n )
|
||||
,.clear ( crc_clear )
|
||||
,.data ( current_word )
|
||||
,.valid ( crc_valid )
|
||||
,.crc ( crc_out )
|
||||
);
|
||||
|
||||
//CRC Contrl
|
||||
|
||||
//crc_clear
|
||||
sirv_gnrl_dffr #(1) crc_clear_dffr (crc2idle, crc_clear, clk, rst_n);
|
||||
|
||||
//crc_valid
|
||||
//sirv_gnrl_dffr #(1) crc_valid_dffr ((state_c == ST_HEAD) || (state_c == ST_DATA) && word_valid, crc_valid, clk, rst_n);
|
||||
assign crc_valid = (state_c == ST_HEAD) || (state_c == ST_DATA) && word_valid;
|
||||
//crc_error
|
||||
sirv_gnrl_dffr #(1) crc_error_dffr (crc2idle && (current_word != crc_out), crc_error, clk, rst_n);
|
||||
|
||||
wire [31:0] frame_status_w;
|
||||
|
||||
assign frame_status_w[2 : 0] = state_c;
|
||||
assign frame_status_w[15: 3] = base_addr[15:3];
|
||||
assign frame_status_w[31:16] = data_len;
|
||||
|
||||
sirv_gnrl_dffr #(32) frame_status_dffr (frame_status_w, frame_status, clk, rst_n);
|
||||
endmodule
|
||||
// ----------------------------------------------------------------------------
|
||||
// Training module (provided in user's file, placeholder here)
|
||||
// Note: To avoid duplication, the definition of ulink_rx_train is omitted.
|
||||
// In actual use, include the original file content here or via `include.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Assume ulink_rx_train module exists, identical to the user-provided code.
|
||||
|
||||
module ulink_rx_train (
|
||||
input logic clk
|
||||
,input logic rst_n
|
||||
,input logic [3 :0] serial_in // 4-lane serial input
|
||||
,input logic [19 :0] patn_count // Training count preset value
|
||||
,input logic frame_error // Frame error indication (from frame module)
|
||||
,input logic frame_done // Frame done indication (from frame module)
|
||||
,input logic [2 :0] tap_step // Delay adjustment step value
|
||||
,input logic [2 :0] tap_adj_mask // Delay adjustment mask
|
||||
,input logic [0 :0] tap_force // Delay force to tap_step
|
||||
,input logic force_train // Force Training
|
||||
,input logic [0 :0] train_en // Training enable
|
||||
,output logic link_down // Link down indication
|
||||
,output logic [2 :0] delay_tap // Delay adjustment value
|
||||
,output logic tap_adj_req
|
||||
,output logic train_ready // Training complete, link ready
|
||||
,output logic [127:0] data_out // Latched parallel data
|
||||
,output logic data_valid
|
||||
,output logic [3 :0] descram_valid
|
||||
,output logic [31 :0] train_status
|
||||
);
|
||||
|
||||
// 4 32-bit shift registers, corresponding to 4 input lanes
|
||||
wire [31:0] lane0_reg, lane1_reg, lane2_reg, lane3_reg;
|
||||
|
||||
sirv_gnrl_dffr #(32) lane0_reg_dffr ({lane0_reg[30:0], serial_in[0]}, lane0_reg, clk, rst_n);
|
||||
sirv_gnrl_dffr #(32) lane1_reg_dffr ({lane1_reg[30:0], serial_in[1]}, lane1_reg, clk, rst_n);
|
||||
sirv_gnrl_dffr #(32) lane2_reg_dffr ({lane2_reg[30:0], serial_in[2]}, lane2_reg, clk, rst_n);
|
||||
sirv_gnrl_dffr #(32) lane3_reg_dffr ({lane3_reg[30:0], serial_in[3]}, lane3_reg, clk, rst_n);
|
||||
|
||||
|
||||
// State definition
|
||||
typedef enum logic [1:0] {
|
||||
SM_DOWN, // Link down
|
||||
SM_MATCH, // Match training pattern
|
||||
SM_EXIT, // Wait for exit pattern
|
||||
SM_READY // Link ready
|
||||
} state_t;
|
||||
|
||||
state_t state_c, state_n;
|
||||
|
||||
localparam TRAINING_PATN = 32'h68666E6C; // "hfnl"
|
||||
localparam TRAINING_EXIT = 32'h65786974; // "exit"
|
||||
|
||||
// Bit counter control
|
||||
wire [4:0] bit_counter;
|
||||
|
||||
wire add_bit_conuter = ((state_c == SM_MATCH) || (state_c == SM_EXIT));
|
||||
wire end_bit_conuter = add_bit_conuter && (bit_counter == 32-1);
|
||||
|
||||
wire [4:0] counter_m1 = end_bit_conuter ? 5'h0 :
|
||||
add_bit_conuter ? bit_counter + 1'b1 :
|
||||
bit_counter ;
|
||||
|
||||
sirv_gnrl_dffr #(5) bit_counter_dffr (counter_m1, bit_counter, clk, rst_n);
|
||||
|
||||
|
||||
// Combinational signals: all four lanes match simultaneously
|
||||
wire match_en = (lane0_reg == TRAINING_PATN) &&
|
||||
(lane1_reg == TRAINING_PATN) &&
|
||||
(lane2_reg == TRAINING_PATN) &&
|
||||
(lane3_reg == TRAINING_PATN);
|
||||
wire match_exit = (lane0_reg == TRAINING_EXIT) &&
|
||||
(lane1_reg == TRAINING_EXIT) &&
|
||||
(lane2_reg == TRAINING_EXIT) &&
|
||||
(lane3_reg == TRAINING_EXIT);
|
||||
wire match_failed = !(match_en | match_exit) & end_bit_conuter;
|
||||
|
||||
// Match counter
|
||||
wire [19:0] match_counter_c;
|
||||
|
||||
|
||||
wire add_match_counter = (state_c == SM_MATCH) && end_bit_conuter;
|
||||
|
||||
wire end_match_counter = add_match_counter && (match_counter_c == patn_count-2);
|
||||
|
||||
wire [19:0] match_counter_n = end_match_counter ? 20'h0 :
|
||||
add_match_counter ? match_counter_c + 1'b1 :
|
||||
match_counter_c ;
|
||||
|
||||
sirv_gnrl_dffr #(20) match_counter_c_dffr (match_counter_n, match_counter_c, clk, rst_n);
|
||||
// ------------------------------------------------------
|
||||
// -- state machine
|
||||
// ------------------------------------------------------
|
||||
|
||||
//jump conditions
|
||||
wire down2match = (state_c == SM_DOWN ) && match_en && train_en;
|
||||
wire match2down = (state_c == SM_MATCH ) && match_failed;
|
||||
wire match2exit = (state_c == SM_MATCH ) && end_match_counter;
|
||||
wire exit2down = (state_c == SM_EXIT ) && match_failed;
|
||||
wire exit2ready = (state_c == SM_EXIT ) && match_exit;
|
||||
wire ready2down = (state_c == SM_READY ) && frame_error;
|
||||
|
||||
|
||||
//state_n
|
||||
assign state_n = ((state_c == SM_DOWN ) && down2match ) ? SM_MATCH :
|
||||
((state_c == SM_MATCH ) && (match2down || force_train )) ? SM_DOWN :
|
||||
((state_c == SM_MATCH ) && match2exit ) ? SM_EXIT :
|
||||
((state_c == SM_EXIT ) && (exit2down || force_train )) ? SM_DOWN :
|
||||
((state_c == SM_EXIT ) && exit2ready ) ? SM_READY :
|
||||
((state_c == SM_READY ) && (ready2down || force_train )) ? SM_DOWN :
|
||||
state_c ;
|
||||
//state_c
|
||||
sirv_gnrl_edffr #(.T(state_t)) state_c_dffr (state_n,state_c,clk, rst_n);
|
||||
// Delay adjustment (step controlled by tap_step)
|
||||
|
||||
wire tap_adj_req_w = (tap_adj_mask[0] && match2down) ||
|
||||
(tap_adj_mask[1] && exit2down ) ||
|
||||
(tap_adj_mask[2] && ready2down) ;
|
||||
|
||||
wire tap_adj_enable = tap_adj_req_w || tap_force;
|
||||
|
||||
wire [2:0] delay_tap_w = tap_force ? tap_step :
|
||||
delay_tap + tap_step ;
|
||||
|
||||
sirv_gnrl_dfflr #(3) delay_tap_dfflr (tap_adj_enable, delay_tap_w, delay_tap, clk, rst_n);
|
||||
|
||||
|
||||
sirv_gnrl_dffr #(1) tap_adj_req_dffr (tap_adj_req_w, tap_adj_req, clk, rst_n);
|
||||
|
||||
// Link status outputs
|
||||
|
||||
sirv_gnrl_dffr #(1) link_down_dffr ((state_c == SM_DOWN), link_down, clk, rst_n);
|
||||
sirv_gnrl_dffr #(1) train_ready_dffr ((state_c == SM_READY), train_ready, clk, rst_n);
|
||||
|
||||
|
||||
// ======================
|
||||
// Data output
|
||||
// ======================
|
||||
wire [127:0] data_buf;
|
||||
sirv_gnrl_dffr #(128) data_buf_dffr ({lane3_reg, lane2_reg, lane1_reg, lane0_reg}, data_buf, clk, rst_n);
|
||||
|
||||
// Frame header constant
|
||||
localparam FRAME_HEADER = 32'hBCBCBCBC;
|
||||
|
||||
// ==============================================================================================================
|
||||
// Data input control: In SM_READY state, latch data every 32 cycles and generate a valid pulse
|
||||
// ==============================================================================================================
|
||||
|
||||
//match_head
|
||||
wire match_head_start;
|
||||
wire match_head = (data_buf[31:0] == FRAME_HEADER);
|
||||
wire match_head_start_w = match_head && train_ready ? 1'b1 :
|
||||
link_down ? 1'b0 :
|
||||
frame_done ? 1'b0 :
|
||||
match_head_start;
|
||||
|
||||
sirv_gnrl_dffr #(1) match_head_start_dffr (match_head_start_w, match_head_start, clk, rst_n);
|
||||
// data counter control
|
||||
wire [4:0] data_counter;
|
||||
|
||||
wire add_data_conuter = match_head_start;
|
||||
wire end_data_conuter = (add_data_conuter && (data_counter == 32-1) || frame_done);
|
||||
|
||||
wire [4:0] data_counter_n = end_data_conuter ? 5'h0 :
|
||||
add_data_conuter ? data_counter + 1'b1 :
|
||||
data_counter ;
|
||||
|
||||
sirv_gnrl_dffr #(5) data_counter_dffr (data_counter_n, data_counter, clk, rst_n);
|
||||
|
||||
//valid_int
|
||||
wire data_valid_w = (state_c == SM_READY) && (match_head || (end_data_conuter && (data_counter == 32-1)));
|
||||
sirv_gnrl_dffr #(1) valid_int_dffr (data_valid_w, data_valid, clk, rst_n);
|
||||
|
||||
//descram_valid
|
||||
wire [3:0] descram_valid_w;
|
||||
assign descram_valid_w[3:1] = {3{data_valid_w}};
|
||||
assign descram_valid_w[0] = (state_c == SM_READY) && (end_data_conuter && (data_counter == 32-1));
|
||||
sirv_gnrl_dffr #(4) descram_valid_dffr (descram_valid_w, descram_valid, clk, rst_n);
|
||||
|
||||
//data_in reg
|
||||
wire data_in_reg;
|
||||
sirv_gnrl_dffr #(128) data_in_reg_dffr (data_buf, data_out, clk, rst_n);
|
||||
|
||||
//train_status
|
||||
wire [31:0] train_status_w;
|
||||
|
||||
assign train_status_w[1 : 0] = state_c;
|
||||
assign train_status_w[2 ] = match_en;
|
||||
assign train_status_w[3 ] = match_exit;
|
||||
assign train_status_w[4 ] = match_failed;
|
||||
assign train_status_w[5 ] = match_head;
|
||||
assign train_status_w[6 ] = match_head_start;
|
||||
assign train_status_w[11: 7] = bit_counter;
|
||||
assign train_status_w[31:12] = match_counter_c;
|
||||
|
||||
sirv_gnrl_dffr #(32) train_status_dffr (train_status_w, train_status, clk, rst_n);
|
||||
|
||||
endmodule
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// prefill Module (used in frame receiver)
|
||||
// ----------------------------------------------------------------------------
|
||||
module prefill #(
|
||||
parameter DELAY = 20'd10000
|
||||
)(
|
||||
input logic clk
|
||||
,input logic rst_n
|
||||
,input logic always_on
|
||||
,input logic prefilling
|
||||
,output logic prefill_start
|
||||
,output logic prefill_done
|
||||
);
|
||||
|
||||
// delay counter control
|
||||
wire [19:0] delay_counter;
|
||||
|
||||
wire add_delay_counter = ~(delay_counter == DELAY);
|
||||
wire end_delay_counter = add_delay_counter && (delay_counter == DELAY-1);
|
||||
|
||||
wire [19:0] delay_counter_n = end_delay_counter ? 20'h0 :
|
||||
add_delay_counter ? delay_counter + 1'b1 :
|
||||
delay_counter ;
|
||||
|
||||
sirv_gnrl_dffr #(20) delay_counter_dffr (delay_counter_n, delay_counter, clk, rst_n);
|
||||
|
||||
//prefill_start
|
||||
sirv_gnrl_dffr #(1) prefill_start_dffr (end_delay_counter, prefill_start, clk, rst_n);
|
||||
|
||||
//prefilling_falling
|
||||
wire [1:0] prefilling_r;
|
||||
sirv_gnrl_dffr #(2) prefilling_r_dffr ({prefilling_r[0],prefilling}, prefilling_r, clk, rst_n);
|
||||
|
||||
wire prefilling_falling = !prefilling_r[0] && prefilling_r[1];
|
||||
//prefill_done
|
||||
sirv_gnrl_dfflr #(1) prefill_done_dfflr (prefilling_falling || always_on, 1'b1, prefill_done, clk, rst_n);
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
|
||||
|
||||
module bhv_spram (
|
||||
clka,
|
||||
ena,
|
||||
dina,
|
||||
addra,
|
||||
|
||||
clkb,
|
||||
enb,
|
||||
doutb,
|
||||
addrb
|
||||
);
|
||||
|
||||
//=================================================
|
||||
function integer clog2(input integer depth);
|
||||
begin
|
||||
for(clog2=0;depth>0;clog2=clog2+1)
|
||||
depth =depth>>1;
|
||||
end
|
||||
endfunction
|
||||
//=================================================
|
||||
parameter width = 16;
|
||||
parameter depth = 1024;
|
||||
localparam aw = clog2(depth-1);
|
||||
//=================================================
|
||||
input clka ;
|
||||
input ena ;
|
||||
input [width-1:0] dina ;
|
||||
input [aw-1:0] addra ;
|
||||
|
||||
input clkb ;
|
||||
input enb ;
|
||||
output [width-1:0] doutb ;
|
||||
input [aw-1:0] addrb ;
|
||||
|
||||
//================================================
|
||||
wire clka;
|
||||
wire ena;
|
||||
wire [width-1:0] dina;
|
||||
wire [aw-1:0] addra;
|
||||
|
||||
wire clkb;
|
||||
wire enb;
|
||||
reg [width-1:0] doutb;
|
||||
wire [aw-1:0] addrb;
|
||||
|
||||
//================================================
|
||||
|
||||
reg [width-1:0] mem[0:depth-1];
|
||||
|
||||
|
||||
|
||||
always@(posedge clka)begin
|
||||
if(ena)begin
|
||||
mem[addra] <=dina;
|
||||
end
|
||||
end
|
||||
|
||||
always@(posedge clkb)begin
|
||||
if(enb)begin
|
||||
doutb <=mem[addrb];
|
||||
end
|
||||
//else begin
|
||||
// doutb <=0;
|
||||
//end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
|
||||
`include "../define/chip_define.v"
|
||||
//`define TSMC_INITIALIZE_MEM
|
||||
module dpram #(
|
||||
parameter DATAWIDTH = 32
|
||||
,parameter ADDRWIDTH = 13
|
||||
)(
|
||||
input PortClk
|
||||
,input [ADDRWIDTH-1 :0] PortAAddr
|
||||
,input [DATAWIDTH-1 :0] PortADataIn
|
||||
,input PortAWriteEnable //active low
|
||||
,input PortAChipEnable //active low
|
||||
,input [(DATAWIDTH/8)-1 :0] PortAByteWriteEnable //active low
|
||||
,output [DATAWIDTH-1 :0] PortADataOut
|
||||
|
||||
,input [ADDRWIDTH-1 :0] PortBAddr
|
||||
,input [DATAWIDTH-1 :0] PortBDataIn
|
||||
,input PortBWriteEnable //active low
|
||||
,input PortBChipEnable //active low
|
||||
,input [(DATAWIDTH/8)-1 :0] PortBByteWriteEnable //active low
|
||||
,output [DATAWIDTH-1 :0] PortBDataOut
|
||||
);
|
||||
|
||||
//==================================================================================
|
||||
//XPM¡¡£í£å£í£ï£ò£ù
|
||||
//==================================================================================
|
||||
|
||||
`ifdef BEHAVIOR_SIM
|
||||
dpram_model #(
|
||||
.DATAWIDTH ( DATAWIDTH )
|
||||
,.ADDRWIDTH ( ADDRWIDTH )
|
||||
) dpram_model (
|
||||
.PortClk ( PortClk )
|
||||
,.PortAWriteEnable ( PortAWriteEnable )
|
||||
,.PortAChipEnable ( PortAChipEnable )
|
||||
,.PortAByteWriteEnable ( PortAByteWriteEnable )
|
||||
,.PortAAddr ( PortAAddr )
|
||||
,.PortADataIn ( PortADataIn )
|
||||
,.PortADataOut ( PortADataOut )
|
||||
,.PortBWriteEnable ( PortBWriteEnable )
|
||||
,.PortBChipEnable ( PortBChipEnable )
|
||||
,.PortBByteWriteEnable ( PortBByteWriteEnable )
|
||||
,.PortBAddr ( PortBAddr )
|
||||
,.PortBDataIn ( PortBDataIn )
|
||||
,.PortBDataOut ( PortBDataOut )
|
||||
);
|
||||
`elsif XILINX_FPGA
|
||||
xil_tdpram #(
|
||||
.DATAWIDTH ( DATAWIDTH )
|
||||
,.ADDRWIDTH ( ADDRWIDTH )
|
||||
) U_xil_tdpram (
|
||||
.PortClk ( PortClk )
|
||||
,.PortAAddr ( PortAAddr )
|
||||
,.PortADataIn ( PortADataIn )
|
||||
,.PortAWriteEnable ( PortAWriteEnable )
|
||||
,.PortAChipEnable ( PortAChipEnable )
|
||||
,.PortAByteWriteEnable ( PortAByteWriteEnable )
|
||||
,.PortADataOut ( PortADataOut )
|
||||
,.PortBAddr ( PortBAddr )
|
||||
,.PortBDataIn ( PortBDataIn )
|
||||
,.PortBWriteEnable ( PortBWriteEnable )
|
||||
,.PortBChipEnable ( PortBChipEnable )
|
||||
,.PortBByteWriteEnable ( PortBByteWriteEnable )
|
||||
,.PortBDataOut ( PortBDataOut )
|
||||
);
|
||||
`elsif TSMC_IC
|
||||
tsmc_dpram #(
|
||||
.DATAWIDTH ( DATAWIDTH )
|
||||
,.ADDRWIDTH ( ADDRWIDTH )
|
||||
) U_tsmc_dpram (
|
||||
.PortClk ( PortClk )
|
||||
,.PortAAddr ( PortAAddr )
|
||||
,.PortADataIn ( PortADataIn )
|
||||
,.PortAWriteEnable ( PortAWriteEnable )
|
||||
,.PortAChipEnable ( PortAChipEnable )
|
||||
,.PortAByteWriteEnable ( PortAByteWriteEnable )
|
||||
,.PortADataOut ( PortADataOut )
|
||||
,.PortBAddr ( PortBAddr )
|
||||
,.PortBDataIn ( PortBDataIn )
|
||||
,.PortBWriteEnable ( PortBWriteEnable )
|
||||
,.PortBChipEnable ( PortBChipEnable )
|
||||
,.PortBByteWriteEnable ( PortBByteWriteEnable )
|
||||
,.PortBDataOut ( PortBDataOut )
|
||||
);
|
||||
`endif
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
`include "../define/chip_undefine.v"
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
//`define FPGA_XIL
|
||||
|
||||
//`define SMIC_IC
|
||||
|
||||
|
||||
`define BEHAVIOUR_SIM
|
||||
|
||||
|
||||
module spram #(
|
||||
parameter width =16,
|
||||
parameter depth =1024
|
||||
|
||||
)(
|
||||
clka,
|
||||
ena,
|
||||
dina,
|
||||
addra,
|
||||
|
||||
clkb,
|
||||
enb,
|
||||
doutb,
|
||||
addrb
|
||||
);
|
||||
///////////////////////////////////////////////////////
|
||||
//Function
|
||||
///////////////////////////////////////////////////////
|
||||
function integer clog2(input integer depth);
|
||||
begin
|
||||
for(clog2=0;depth>0;clog2=clog2+1)
|
||||
depth =depth>>1;
|
||||
end
|
||||
endfunction
|
||||
|
||||
localparam aw = clog2(depth-1);
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//Input declaration
|
||||
///////////////////////////////////////////////////////
|
||||
input clka;
|
||||
input ena;
|
||||
input [width-1:0] dina;
|
||||
input [aw-1:0] addra;
|
||||
|
||||
input clkb;
|
||||
input enb;
|
||||
output [width-1:0] doutb;
|
||||
input [aw-1:0] addrb;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//SRAM
|
||||
///////////////////////////////////////////////////////
|
||||
`ifdef BEHAVIOUR_SIM
|
||||
bhv_spram #(
|
||||
.width (width ),
|
||||
.depth (depth )
|
||||
)bhv_spram(
|
||||
.clka (clka ),
|
||||
.ena (ena ),
|
||||
.dina (dina ),
|
||||
.addra (addra ),
|
||||
.clkb (clkb ),
|
||||
.enb (enb ),
|
||||
.doutb (doutb ),
|
||||
.addrb (addrb )
|
||||
);
|
||||
|
||||
`elsif XINLINX_FPGA
|
||||
xil_spram #(
|
||||
.dw (width ),
|
||||
.depth (depth )
|
||||
)xil_spram(
|
||||
.wrclk (clka ),
|
||||
.wren (ena ),
|
||||
.wrdata (dina ),
|
||||
.wraddr (addra ),
|
||||
.rdclk (clkb ),
|
||||
.rden (enb ),
|
||||
.rddata (doutb ),
|
||||
.rdaddr (addrb )
|
||||
);
|
||||
`elsif SMIC_IC
|
||||
smic_spram #(
|
||||
.width (width),
|
||||
.depth (depth)
|
||||
)smic_spram(
|
||||
.CLKB (clka ),
|
||||
.CENB (ena ),
|
||||
.AB (addra ),
|
||||
.DB (dina ),
|
||||
|
||||
.CLKA (clkb ),
|
||||
.CENA (enb ),
|
||||
.AA (addrb ),
|
||||
.QA (doutb )
|
||||
);
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
//`undef FPGA_XIL
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
//`define FPGA_XIL
|
||||
|
||||
//`define SMIC_IC
|
||||
|
||||
|
||||
`define BEHAVIOUR_SIM
|
||||
|
||||
|
||||
module spram #(
|
||||
parameter width =16,
|
||||
parameter depth =1024
|
||||
|
||||
)(
|
||||
clka,
|
||||
ena,
|
||||
dina,
|
||||
addra,
|
||||
|
||||
clkb,
|
||||
enb,
|
||||
doutb,
|
||||
addrb
|
||||
);
|
||||
///////////////////////////////////////////////////////
|
||||
//Function
|
||||
///////////////////////////////////////////////////////
|
||||
function integer clog2(input integer depth);
|
||||
begin
|
||||
for(clog2=0;depth>0;clog2=clog2+1)
|
||||
depth =depth>>1;
|
||||
end
|
||||
endfunction
|
||||
|
||||
localparam aw = clog2(depth-1);
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//Input declaration
|
||||
///////////////////////////////////////////////////////
|
||||
input clka;
|
||||
input ena;
|
||||
input [width-1:0] dina;
|
||||
input [aw-1:0] addra;
|
||||
|
||||
input clkb;
|
||||
input enb;
|
||||
output [width-1:0] doutb;
|
||||
input [aw-1:0] addrb;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//SRAM
|
||||
///////////////////////////////////////////////////////
|
||||
`ifdef BEHAVIOUR_SIM
|
||||
bhv_spram #(
|
||||
.width (width ),
|
||||
.depth (depth )
|
||||
)bhv_spram(
|
||||
.clka (clka ),
|
||||
.ena (ena ),
|
||||
.dina (dina ),
|
||||
.addra (addra ),
|
||||
.clkb (clkb ),
|
||||
.enb (enb ),
|
||||
.doutb (doutb ),
|
||||
.addrb (addrb )
|
||||
);
|
||||
|
||||
`elsif XINLINX_FPGA
|
||||
xil_spram #(
|
||||
.dw (width ),
|
||||
.depth (depth )
|
||||
)xil_spram(
|
||||
.wrclk (clka ),
|
||||
.wren (ena ),
|
||||
.wrdata (dina ),
|
||||
.wraddr (addra ),
|
||||
.rdclk (clkb ),
|
||||
.rden (enb ),
|
||||
.rddata (doutb ),
|
||||
.rdaddr (addrb )
|
||||
);
|
||||
`elsif SMIC_IC
|
||||
smic_spram #(
|
||||
.width (width),
|
||||
.depth (depth)
|
||||
)smic_spram(
|
||||
.CLKB (clka ),
|
||||
.CENB (ena ),
|
||||
.AB (addra ),
|
||||
.DB (dina ),
|
||||
|
||||
.CLKA (clkb ),
|
||||
.CENA (enb ),
|
||||
.AA (addrb ),
|
||||
.QA (doutb )
|
||||
);
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
//`undef FPGA_XIL
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
|
||||
/*
|
||||
// module dmux
|
||||
module sram_dmux_m #(
|
||||
parameter ADDR_WIDTH_I = 11, // input port addr width
|
||||
parameter ADDR_WIDTH_O = 10, // output port addr width
|
||||
parameter DATA_WIDTH = 64 // in/output port data width
|
||||
)(
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
sram_if.slave port_in,
|
||||
sram_if.master port_out[2**(ADDR_WIDTH_I-ADDR_WIDTH_O)-1:0]
|
||||
);
|
||||
localparam ASEL_WIDTH = ADDR_WIDTH_I-ADDR_WIDTH_O;
|
||||
logic [ASEL_WIDTH-1:0] data_sel, data_out_sel;
|
||||
assign data_sel = port_in.addr[ADDR_WIDTH_I-1 : ADDR_WIDTH_O];
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
data_out_sel <= 0;
|
||||
end else begin
|
||||
data_out_sel <= data_sel;
|
||||
end
|
||||
end
|
||||
|
||||
logic [DATA_WIDTH-1:0] dout_data[2**(ASEL_WIDTH)-1:0];
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < 2**ASEL_WIDTH; i++) begin
|
||||
assign port_out[i].addr = (i == data_sel) ? port_in.addr[ADDR_WIDTH_O-1:0] : 0;
|
||||
assign port_out[i].wren = (i == data_sel) ? port_in.wren : 0;
|
||||
assign port_out[i].rden = (i == data_sel) ? port_in.rden : 0;
|
||||
assign port_out[i].din = (i == data_sel) ? port_in.din : 0;
|
||||
assign port_out[i].wben = (i == data_sel) ? port_in.wben : 0;
|
||||
assign dout_data[i]= port_out[i].dout;
|
||||
end
|
||||
endgenerate
|
||||
assign port_in.dout = dout_data[data_out_sel];
|
||||
|
||||
endmodule
|
||||
*/
|
||||
|
||||
// word dmux
|
||||
module sram_dmux_w #(
|
||||
parameter ADDR_WIDTH = 11, // input port addr width
|
||||
parameter DATA_WIDTH_I = 32, // input port data width
|
||||
parameter DATA_WIDTH_O = 64 // output port data width
|
||||
)(
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
sram_if.slave port_in,
|
||||
sram_if.master port_out
|
||||
);
|
||||
|
||||
// calculate and buffer word select bit
|
||||
localparam DL = $clog2(DATA_WIDTH_I/8);
|
||||
localparam DH = $clog2(DATA_WIDTH_O/8);
|
||||
localparam WSEL_WIDTH = DH - DL;
|
||||
logic [WSEL_WIDTH-1:0] data_sel, data_out_sel;
|
||||
assign data_sel = port_in.addr[DH-1:DL];
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
data_out_sel <= 0;
|
||||
end else begin
|
||||
data_out_sel <= data_sel;
|
||||
end
|
||||
end
|
||||
//
|
||||
assign port_out.addr = port_in.addr;
|
||||
assign port_out.wren = port_in.wren;
|
||||
assign port_out.rden = port_in.rden;
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < 2**(WSEL_WIDTH); i++) begin
|
||||
assign port_out.din[DATA_WIDTH_I*i +: DATA_WIDTH_I] = (i == data_sel) ? port_in.din : 0;
|
||||
assign port_out.wben[DATA_WIDTH_I/8*i +: DATA_WIDTH_I/8] = (i == data_sel) ? port_in.wben : 0;
|
||||
end
|
||||
endgenerate
|
||||
assign port_in.dout = port_out.dout[DATA_WIDTH_I*data_out_sel +: DATA_WIDTH_I];
|
||||
|
||||
endmodule
|
||||
|
||||
/*
|
||||
// data split
|
||||
module sram_split #(
|
||||
parameter ADDR_WIDTH = 11, // input port addr width
|
||||
parameter DATA_WIDTH_I = 64, // input port data width
|
||||
parameter DATA_WIDTH_O = 32 // output port data width
|
||||
)(
|
||||
sram_if.slave port_in,
|
||||
sram_if.master port_out[DATA_WIDTH_I/DATA_WIDTH_O-1:0]
|
||||
);
|
||||
localparam DH = $clog2(DATA_WIDTH_I/8);
|
||||
localparam DL = $clog2(DATA_WIDTH_O/8);
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < DATA_WIDTH_I/DATA_WIDTH_O; i++) begin
|
||||
assign port_out[i].addr = {port_in.addr[ADDR_WIDTH-1:DH], {DL{1'b0}}};
|
||||
assign port_out[i].rden = port_in.rden;
|
||||
assign port_out[i].wren = port_in.wren;
|
||||
assign port_out[i].din = port_in.din[i*DATA_WIDTH_O +: DATA_WIDTH_O];
|
||||
assign port_out[i].wben = port_in.wben[i*DATA_WIDTH_O/8 +: DATA_WIDTH_O/8];
|
||||
assign port_in.dout[i*DATA_WIDTH_O +: DATA_WIDTH_O] = port_out[i].dout;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
*/
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
interface sram_if #(parameter ADDR_WIDTH = 8, parameter DATA_WIDTH = 32)(input bit clk);
|
||||
// Signals for interfacing with the SRAM
|
||||
logic [ADDR_WIDTH-1:0] addr;
|
||||
logic [DATA_WIDTH-1:0] din;
|
||||
logic [DATA_WIDTH-1:0] dout;
|
||||
logic rden;
|
||||
logic wren;
|
||||
logic [DATA_WIDTH/8-1:0] wben;
|
||||
|
||||
modport master(
|
||||
output addr,
|
||||
output din,
|
||||
input dout,
|
||||
output wren,
|
||||
output rden,
|
||||
output wben
|
||||
);
|
||||
|
||||
modport slave (
|
||||
input addr,
|
||||
input din,
|
||||
output dout,
|
||||
input wren,
|
||||
input rden,
|
||||
input wben
|
||||
);
|
||||
/*
|
||||
// synopsys translate_off
|
||||
// write operation
|
||||
task write;
|
||||
input logic [ADDR_WIDTH-1:0] addr_in;
|
||||
input logic [DATA_WIDTH-1:0] data_in;
|
||||
input logic [DATA_WIDTH/8-1:0] byte_enable;
|
||||
begin
|
||||
addr = addr_in;
|
||||
din = data_in;
|
||||
wben = byte_enable;
|
||||
wren = 1;
|
||||
rden = 0;
|
||||
@(posedge clk);
|
||||
wren = 0;
|
||||
end
|
||||
endtask
|
||||
|
||||
// read oepration
|
||||
task read;
|
||||
input logic [ADDR_WIDTH-1:0] addr_in;
|
||||
begin
|
||||
addr = addr_in;
|
||||
wren = 0;
|
||||
rden = 1;
|
||||
@(posedge clk);
|
||||
rden = 0;
|
||||
end
|
||||
endtask
|
||||
// synopsys translate_on
|
||||
*/
|
||||
endinterface
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
|
||||
|
||||
module tsmc_dpram #(
|
||||
parameter DATAWIDTH = 32
|
||||
,parameter ADDRWIDTH = 14
|
||||
)(
|
||||
input PortClk
|
||||
,input [ADDRWIDTH-1 :0] PortAAddr
|
||||
,input [DATAWIDTH-1 :0] PortADataIn
|
||||
,input PortAWriteEnable //active low
|
||||
,input PortAChipEnable //active low
|
||||
,input [(DATAWIDTH/8)-1 :0] PortAByteWriteEnable //active low
|
||||
,output [DATAWIDTH-1 :0] PortADataOut
|
||||
|
||||
,input [ADDRWIDTH-1 :0] PortBAddr
|
||||
,input [DATAWIDTH-1 :0] PortBDataIn
|
||||
,input PortBWriteEnable //active low
|
||||
,input PortBChipEnable //active low
|
||||
,input [(DATAWIDTH/8)-1 :0] PortBByteWriteEnable //active low
|
||||
,output [DATAWIDTH-1 :0] PortBDataOut
|
||||
);
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
function integer clog2(input integer bit_depth);
|
||||
begin
|
||||
for(clog2=0;bit_depth>0;clog2=clog2+1)
|
||||
bit_depth =bit_depth>>1;
|
||||
end
|
||||
endfunction
|
||||
|
||||
localparam LSB = clog2(DATAWIDTH/8 -1);
|
||||
|
||||
generate
|
||||
if((DATAWIDTH == 512) && (ADDRWIDTH == 19)) begin:spram_512X8192_generation
|
||||
genvar i;
|
||||
wire [DATAWIDTH-1:0] BWEBA ;
|
||||
wire [DATAWIDTH-1:0] BWEBB ;
|
||||
for(i = 0; i < DATAWIDTH/8; i = i + 1) begin
|
||||
assign BWEBA[8*i +: 8] = {8{PortAByteWriteEnable[i]}};
|
||||
assign BWEBB[8*i +: 8] = {8{PortBByteWriteEnable[i]}};
|
||||
end
|
||||
genvar k;
|
||||
wire [1 :0] U_CEBA;
|
||||
wire [1 :0] U_CEBB;
|
||||
wire [DATAWIDTH-1:0] U_QA[1 :0];
|
||||
wire [DATAWIDTH-1:0] U_QB[1 :0];
|
||||
reg [1 :0] AA_1D_MSB;
|
||||
reg [1 :0] AB_1D_MSB;
|
||||
for(k = 0; k < 2; k = k + 1) begin
|
||||
assign U_CEBA[k] = ~(PortAAddr[ADDRWIDTH-1] == k) | PortAChipEnable;
|
||||
assign U_CEBB[k] = ~(PortBAddr[ADDRWIDTH-1] == k) | PortBChipEnable;
|
||||
tsdn28hpcpuhdb4096x128m4mw_170a U0_tsdn28hpcpuhdb4096x128m4mw_170a (
|
||||
.CLK ( PortClk )
|
||||
,.CEBA ( U_CEBA[k] )
|
||||
,.WEBA ( PortAWriteEnable )
|
||||
,.BWEBA ( BWEBA[127:0] )
|
||||
,.AA ( PortAAddr[ADDRWIDTH-2:LSB] )
|
||||
,.DA ( PortADataIn[127:0] )
|
||||
,.QA ( U_QA[k][127:0] )
|
||||
,.CEBB ( U_CEBB[k] )
|
||||
,.WEBB ( PortBWriteEnable )
|
||||
,.BWEBB ( BWEBB[127:0] )
|
||||
,.AB ( PortBAddr[ADDRWIDTH-2:LSB] )
|
||||
,.DB ( PortBDataIn[127:0] )
|
||||
,.QB ( U_QB[k][127:0] )
|
||||
,.RTSEL ( 2'b00 )
|
||||
,.WTSEL ( 2'b00 )
|
||||
,.PTSEL ( 2'b00 )
|
||||
);
|
||||
tsdn28hpcpuhdb4096x128m4mw_170a U1_tsdn28hpcpuhdb4096x128m4mw_170a (
|
||||
.CLK ( PortClk )
|
||||
,.CEBA ( U_CEBA[k] )
|
||||
,.WEBA ( PortAWriteEnable )
|
||||
,.BWEBA ( BWEBA[255:128] )
|
||||
,.AA ( PortAAddr[ADDRWIDTH-2:LSB] )
|
||||
,.DA ( PortADataIn[255:128] )
|
||||
,.QA ( U_QA[k][255:128] )
|
||||
,.CEBB ( U_CEBB[k] )
|
||||
,.WEBB ( PortBWriteEnable )
|
||||
,.BWEBB ( BWEBB[255:128] )
|
||||
,.AB ( PortBAddr[ADDRWIDTH-2:LSB] )
|
||||
,.DB ( PortBDataIn[255:128] )
|
||||
,.QB ( U_QB[k][255:128] )
|
||||
,.RTSEL ( 2'b00 )
|
||||
,.WTSEL ( 2'b00 )
|
||||
,.PTSEL ( 2'b00 )
|
||||
);
|
||||
tsdn28hpcpuhdb4096x128m4mw_170a U2_tsdn28hpcpuhdb4096x128m4mw_170a (
|
||||
.CLK ( PortClk )
|
||||
,.CEBA ( U_CEBA[k] )
|
||||
,.WEBA ( PortAWriteEnable )
|
||||
,.BWEBA ( BWEBA[383:256] )
|
||||
,.AA ( PortAAddr[ADDRWIDTH-2:LSB] )
|
||||
,.DA ( PortADataIn[383:256] )
|
||||
,.QA ( U_QA[k][383:256] )
|
||||
,.CEBB ( U_CEBB[k] )
|
||||
,.WEBB ( PortBWriteEnable )
|
||||
,.BWEBB ( BWEBB[383:256] )
|
||||
,.AB ( PortBAddr[ADDRWIDTH-2:LSB] )
|
||||
,.DB ( PortBDataIn[383:256] )
|
||||
,.QB ( U_QB[k][383:256] )
|
||||
,.RTSEL ( 2'b00 )
|
||||
,.WTSEL ( 2'b00 )
|
||||
,.PTSEL ( 2'b00 )
|
||||
);
|
||||
tsdn28hpcpuhdb4096x128m4mw_170a U3_tsdn28hpcpuhdb4096x128m4mw_170a (
|
||||
.CLK ( PortClk )
|
||||
,.CEBA ( U_CEBA[k] )
|
||||
,.WEBA ( PortAWriteEnable )
|
||||
,.BWEBA ( BWEBA[511:384] )
|
||||
,.AA ( PortAAddr[ADDRWIDTH-2:LSB] )
|
||||
,.DA ( PortADataIn[511:384] )
|
||||
,.QA ( U_QA[k][511:384] )
|
||||
,.CEBB ( U_CEBB[k] )
|
||||
,.WEBB ( PortBWriteEnable )
|
||||
,.BWEBB ( BWEBB[511:384] )
|
||||
,.AB ( PortBAddr[ADDRWIDTH-2:LSB] )
|
||||
,.DB ( PortBDataIn[511:384] )
|
||||
,.QB ( U_QB[k][511:384] )
|
||||
,.RTSEL ( 2'b00 )
|
||||
,.WTSEL ( 2'b00 )
|
||||
,.PTSEL ( 2'b00 )
|
||||
);
|
||||
end
|
||||
always @(posedge PortClk) begin
|
||||
if(PortAWriteEnable == 1'b1) begin
|
||||
AA_1D_MSB <= PortAAddr[ADDRWIDTH-1];
|
||||
end
|
||||
else begin
|
||||
AA_1D_MSB <= AA_1D_MSB;
|
||||
end
|
||||
end
|
||||
always @(posedge PortClk) begin
|
||||
if(PortBWriteEnable == 1'b1) begin
|
||||
AB_1D_MSB <= PortBAddr[ADDRWIDTH-1];
|
||||
end
|
||||
else begin
|
||||
AB_1D_MSB <= AB_1D_MSB;
|
||||
end
|
||||
end
|
||||
assign PortADataOut = {DATAWIDTH{AA_1D_MSB == 1'h0}} & U_QA[0]
|
||||
| {DATAWIDTH{AA_1D_MSB == 1'h1}} & U_QA[1]
|
||||
;
|
||||
assign PortBDataOut = {DATAWIDTH{AB_1D_MSB == 1'h0}} & U_QB[0]
|
||||
| {DATAWIDTH{AB_1D_MSB == 1'h1}} & U_QB[1]
|
||||
;
|
||||
end
|
||||
else begin:dpram_model_generation
|
||||
dpram_model #(
|
||||
.DATAWIDTH ( DATAWIDTH )
|
||||
,.ADDRWIDTH ( ADDRWIDTH-LSB )
|
||||
) U_dpram_model (
|
||||
.PortClk ( PortClk )
|
||||
,.PortAWriteEnable ( PortAWriteEnable )
|
||||
,.PortAChipEnable ( PortAChipEnable )
|
||||
,.PortAByteWriteEnable ( PortAByteWriteEnable )
|
||||
,.PortAAddr ( PortAAddr[ADDRWIDTH-1:LSB] )
|
||||
,.PortADataIn ( PortADataIn )
|
||||
,.PortADataOut ( PortADataOut )
|
||||
,.PortBWriteEnable ( PortBWriteEnable )
|
||||
,.PortBChipEnable ( PortBChipEnable )
|
||||
,.PortBByteWriteEnable ( PortBByteWriteEnable )
|
||||
,.PortBAddr ( PortBAddr[ADDRWIDTH-1:LSB] )
|
||||
,.PortBDataIn ( PortBDataIn )
|
||||
,.PortBDataOut ( PortBDataOut )
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 2019/07/03 13:29:31
|
||||
// Design Name:
|
||||
// Module Name: xil_tdpram
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//`define XINLINX_FPGA
|
||||
|
||||
module xil_tdpram #(
|
||||
parameter DATAWIDTH = 32
|
||||
,parameter ADDRWIDTH = 12
|
||||
)(
|
||||
input PortClk
|
||||
,input [ADDRWIDTH-1 :0] PortAAddr
|
||||
,input [DATAWIDTH-1 :0] PortADataIn
|
||||
,input PortAWriteEnable //active low
|
||||
,input PortAChipEnable //active low
|
||||
,input [(DATAWIDTH/8)-1 :0] PortAByteWriteEnable //active low
|
||||
,output [DATAWIDTH-1 :0] PortADataOut
|
||||
|
||||
,input [ADDRWIDTH-1 :0] PortBAddr
|
||||
,input [DATAWIDTH-1 :0] PortBDataIn
|
||||
,input PortBWriteEnable //active low
|
||||
,input PortBChipEnable //active low
|
||||
,input [(DATAWIDTH/8)-1 :0] PortBByteWriteEnable //active low
|
||||
,output [DATAWIDTH-1 :0] PortBDataOut
|
||||
);
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
function integer clog2(input integer bit_depth);
|
||||
begin
|
||||
for(clog2=0;bit_depth>0;clog2=clog2+1)
|
||||
bit_depth =bit_depth>>1;
|
||||
end
|
||||
endfunction
|
||||
|
||||
localparam LSB = clog2(DATAWIDTH/8 -1);
|
||||
localparam MAW = ADDRWIDTH - LSB;
|
||||
localparam MB =(DATAWIDTH)*(32'h0000_0001<<MAW);
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//XPM
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
wire [(DATAWIDTH/8)-1 :0] PortAByteWriteEnable_w = {(DATAWIDTH/8){PortAWriteEnable | PortAChipEnable}} | PortAByteWriteEnable;
|
||||
wire [(DATAWIDTH/8)-1 :0] PortBByteWriteEnable_w = {(DATAWIDTH/8){PortBWriteEnable | PortBChipEnable}} | PortBByteWriteEnable;
|
||||
xpm_memory_tdpram #(
|
||||
.CLOCKING_MODE ( "common_clock" ) // String
|
||||
,.ECC_MODE ( "no_ecc" ) // String
|
||||
,.MEMORY_INIT_FILE ( "none" ) // String
|
||||
,.MEMORY_INIT_PARAM ( "0" ) // String
|
||||
,.MEMORY_OPTIMIZATION ( "true" ) // String
|
||||
,.MEMORY_PRIMITIVE ( "auto" ) // String
|
||||
,.AUTO_SLEEP_TIME ( 0 ) // DECIMAL
|
||||
,.CASCADE_HEIGHT ( 0 ) // DECIMAL
|
||||
,.SIM_ASSERT_CHK ( 0 ) // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
|
||||
,.USE_EMBEDDED_CONSTRAINT ( 0 ) // DECIMAL
|
||||
,.USE_MEM_INIT ( 1 ) // DECIMAL
|
||||
,.WAKEUP_TIME ( "disable_sleep" ) // String
|
||||
,.MESSAGE_CONTROL ( 0 ) // DECIMAL
|
||||
,.MEMORY_SIZE ( MB ) // DECIMAL
|
||||
|
||||
,.ADDR_WIDTH_A ( MAW ) // DECIMAL
|
||||
,.BYTE_WRITE_WIDTH_A ( 8 ) // DECIMAL
|
||||
,.WRITE_DATA_WIDTH_A ( DATAWIDTH ) // DECIMAL
|
||||
,.READ_DATA_WIDTH_A ( DATAWIDTH ) // DECIMAL
|
||||
,.READ_LATENCY_A ( 1 ) // DECIMAL
|
||||
,.READ_RESET_VALUE_A ( "0" ) // String
|
||||
,.RST_MODE_A ( "SYNC" ) // String
|
||||
,.WRITE_MODE_A ( "no_change" ) // String
|
||||
|
||||
,.ADDR_WIDTH_B ( MAW ) // DECIMAL
|
||||
,.BYTE_WRITE_WIDTH_B ( 8 ) // DECIMAL
|
||||
,.WRITE_DATA_WIDTH_B ( DATAWIDTH ) // DECIMAL
|
||||
,.READ_DATA_WIDTH_B ( DATAWIDTH ) // DECIMAL
|
||||
,.READ_LATENCY_B ( 1 ) // DECIMAL
|
||||
,.READ_RESET_VALUE_B ( "0" ) // String
|
||||
,.RST_MODE_B ( "SYNC" ) // String
|
||||
,.WRITE_MODE_B ( "no_change" ) // String
|
||||
) xpm_memory_tdpram_inst (
|
||||
|
||||
.rsta ( 0 ) // 1-bit input: Reset signal for the final port A output register stage.
|
||||
// Synchronously resets output port douta to the value specified by
|
||||
// parameter READ_RESET_VALUE_A.
|
||||
,.clka ( PortClk ) // 1-bit input: Clock signal for port A. Also clocks port B when
|
||||
// parameter CLOCKING_MODE is "common_clock".
|
||||
,.regcea ( 0 ) // 1-bit input: Clock Enable for the last register stage on the output
|
||||
// data path.
|
||||
,.ena ( 1'b1 ) // 1-bit input: Memory enable signal for port A. Must be high on clock
|
||||
// cycles when read or write operations are initiated. Pipelined
|
||||
// internally.
|
||||
,.wea ( ~PortAByteWriteEnable_w ) // WRITE_DATA_WIDTH_A/BYTE_WRITE_WIDTH_A-bit input: Write enable vector
|
||||
// for port A input data port dina. 1 bit wide when word-wide writes are
|
||||
// used. In byte-wide write configurations, each bit controls the
|
||||
// writing one byte of dina to address addra. For example, to
|
||||
// synchronously write only bits [15-8] of dina when WRITE_DATA_WIDTH_A
|
||||
// is 32, wea would be 4'b0010.
|
||||
,.addra ( PortAAddr[ADDRWIDTH-1 : LSB] ) // ADDR_WIDTH_A-bit input: Address for port A write and read operations.
|
||||
,.dina ( PortADataIn ) // WRITE_DATA_WIDTH_A-bit input: Data input for port A write operations.
|
||||
,.douta ( PortADataOut ) // READ_DATA_WIDTH_A-bit output: Data output for port A read operations.
|
||||
,.dbiterra ( ) // 1-bit output: Status signal to indicate double bit error occurrence
|
||||
// on the data output of port A.
|
||||
,.sbiterra ( ) // 1-bit output: Status signal to indicate single bit error occurrence
|
||||
// on the data output of port A.
|
||||
,.injectdbiterra ( 1'b0 ) // 1-bit input: Controls double bit error injection on input data when
|
||||
// ECC enabled (Error injection capability is not available in
|
||||
// "decode_only" mode).
|
||||
,.injectsbiterra ( 1'b0 ) // 1-bit input: Controls single bit error injection on input data when
|
||||
// ECC enabled (Error injection capability is not available in
|
||||
// "decode_only" mode).
|
||||
|
||||
,.rstb ( 0 ) // 1-bit input: Reset signal for the final port B output register stage.
|
||||
// Synchronously resets output port douta to the value specified by
|
||||
// parameter READ_RESET_VALUE_B.
|
||||
,.clkb ( PortClk ) // 1-bit input: Clock signal for port B. Also clocks port A when
|
||||
// parameter CLOCKING_MODE is "common_clock".
|
||||
,.regceb ( 0 ) // 1-bit input: Clock Enable for the last register stage on the output
|
||||
// data path.
|
||||
,.enb ( 1'b1 ) // 1-bit input: Memory enable signal for port B. Must be high on clock
|
||||
// cycles when read or write operations are initiated. Pipelined
|
||||
// internally.
|
||||
,.web ( ~PortBByteWriteEnable_w ) // WRITE_DATA_WIDTH_B/BYTE_WRITE_WIDTH_B-bit input: Write enable vector
|
||||
// for port B input data port dina. 1 bit wide when word-wide writes are
|
||||
// used. In byte-wide write configurations, each bit controls the
|
||||
// writing one byte of dinb to address addrb. For example, to
|
||||
// synchronously write only bits [15-8] of dina when WRITE_DATA_WIDTH_B
|
||||
// is 32, wea would be 4'b0010.
|
||||
,.addrb ( PortBAddr[ADDRWIDTH-1 : LSB] ) // ADDR_WIDTH_B-bit input: Address for port B write and read operations.
|
||||
,.dinb ( PortBDataIn ) // WRITE_DATA_WIDTH_A-bit input: Data input for port B write operations.
|
||||
,.doutb ( PortBDataOut ) // READ_DATA_WIDTH_A-bit output: Data output for port B read operations.
|
||||
,.dbiterrb ( ) // 1-bit output: Status signal to indicate double bit error occurrence
|
||||
// on the data output of port B.
|
||||
,.sbiterrb ( ) // 1-bit output: Status signal to indicate single bit error occurrence
|
||||
// on the data output of port B.
|
||||
,.injectdbiterrb ( 1'b0 ) // 1-bit input: Controls double bit error injection on input data when
|
||||
// ECC enabled (Error injection capability is not available in
|
||||
// "decode_only" mode).
|
||||
,.injectsbiterrb ( 1'b0 ) // 1-bit input: Controls single bit error injection on input data when
|
||||
// ECC enabled (Error injection capability is not available in
|
||||
// "decode_only" mode).
|
||||
,.sleep ( 1'b0 ) // 1-bit input: sleep signal to enable the dynamic power saving feature.
|
||||
);
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
`timescale 1ns/1ps
|
||||
//====================================================
|
||||
//Author : pwy
|
||||
//Date : 2024-04-04
|
||||
//Des : async set & sync release management unit
|
||||
//====================================================
|
||||
module rst_gen_unit(
|
||||
//ext hardware async reset -- low active
|
||||
input async_rstn_i
|
||||
//power-on reset -- low active
|
||||
,input por_rstn_i
|
||||
//sys soft reset -- low active
|
||||
,input sys_soft_resetn_i
|
||||
//ch0 soft reset -- low active
|
||||
,input ch0_soft_rstn_i
|
||||
//ch1 soft reset -- low active
|
||||
,input ch1_soft_rstn_i
|
||||
//ch2 soft reset -- low active
|
||||
,input ch2_soft_rstn_i
|
||||
//ch3 soft reset -- low active
|
||||
,input ch3_soft_rstn_i
|
||||
//clock
|
||||
,input clk
|
||||
//reset output -- low active
|
||||
,output ch0_rstn_o
|
||||
,output ch1_rstn_o
|
||||
,output ch2_rstn_o
|
||||
,output ch3_rstn_o
|
||||
//Phase-locked loop reset -- low active
|
||||
,output pll_rstn_o
|
||||
);
|
||||
|
||||
//ch0 reset --> async_rstn_i & por_rstn_i & sys_soft_resetn_i & ch0_soft_rstn_i
|
||||
rst_sync ch0_rstn_sync (
|
||||
.clk_d ( clk )
|
||||
,.async_rstn ( async_rstn_i & por_rstn_i & sys_soft_resetn_i & ch0_soft_rstn_i )
|
||||
,.sync_rstn ( ch0_rstn_o )
|
||||
);
|
||||
|
||||
//ch1 reset --> async_rstn_i & por_rstn_i & sys_soft_resetn_i & ch1_soft_rstn_i
|
||||
rst_sync ch1_rstn_sync (
|
||||
.clk_d ( clk )
|
||||
,.async_rstn ( async_rstn_i & por_rstn_i & sys_soft_resetn_i & ch1_soft_rstn_i )
|
||||
,.sync_rstn ( ch1_rstn_o )
|
||||
);
|
||||
|
||||
//ch2 reset --> async_rstn_i & por_rstn_i & sys_soft_resetn_i & ch2_soft_rstn_i
|
||||
rst_sync ch2_rstn_sync (
|
||||
.clk_d ( clk )
|
||||
,.async_rstn ( async_rstn_i & por_rstn_i & sys_soft_resetn_i & ch2_soft_rstn_i )
|
||||
,.sync_rstn ( ch2_rstn_o )
|
||||
);
|
||||
|
||||
//ch3 reset --> async_rstn_i & por_rstn_i & sys_soft_resetn_i & ch3_soft_rstn_i
|
||||
rst_sync ch3_rstn_sync (
|
||||
.clk_d ( clk )
|
||||
,.async_rstn ( async_rstn_i & por_rstn_i & sys_soft_resetn_i & ch3_soft_rstn_i )
|
||||
,.sync_rstn ( ch3_rstn_o )
|
||||
);
|
||||
|
||||
//Phase-locked loop reset -- low active
|
||||
assign pll_rstn_o = async_rstn_i & por_rstn_i;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
`timescale 1ns/1ps
|
||||
//====================================================
|
||||
//Author : pwy
|
||||
//Date : 2020-06-24
|
||||
//Des : async set & sync release
|
||||
//====================================================
|
||||
module rst_sync(
|
||||
input clk_d ,
|
||||
input async_rstn ,
|
||||
output sync_rstn
|
||||
);
|
||||
|
||||
reg rstn_s1;
|
||||
reg rstn_s2;
|
||||
|
||||
always@(posedge clk_d or negedge async_rstn)begin
|
||||
if(!async_rstn)begin
|
||||
rstn_s1 <=1'b0;
|
||||
rstn_s2 <=1'b0;
|
||||
end
|
||||
else begin
|
||||
rstn_s1 <=1'b1;
|
||||
rstn_s2 <=rstn_s1;
|
||||
end
|
||||
end
|
||||
|
||||
assign sync_rstn = rstn_s2;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
//+FHDR--------------------------------------------------------------------------------------------------------
|
||||
// Company:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// File Name : spi_bus_decoder.v
|
||||
// Department :
|
||||
// Author : PWY
|
||||
// Author's Tel :
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Relese History
|
||||
// Version Date Author Description
|
||||
// 0.1 2024-03-13 PWY Serial Peripheral Interface BUS Decoder
|
||||
// 0.2 2024-06-15 PWY The slave interface address will be reduced from 25 bits to 20 bits.
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Keywords :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Parameter
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Target Device:
|
||||
// Tool versions:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Reuse Issues
|
||||
// Reset Strategy:
|
||||
// Clock Domains:
|
||||
// Critical Timing:
|
||||
// Asynchronous I/F:
|
||||
// Synthesizable (y/n):
|
||||
// Other:
|
||||
//-FHDR--------------------------------------------------------------------------------------------------------
|
||||
|
||||
module spi_bus_decoder #(
|
||||
parameter SLVNUM = 32
|
||||
,parameter SPIBUS_CMD_REG = 1
|
||||
,parameter SPIBUS_OUT_REG = 1
|
||||
)(
|
||||
input clk
|
||||
,input rst_n
|
||||
,sram_if.slave mst
|
||||
,sram_if.master slv [SLVNUM-1:0] //s and m exchange
|
||||
);
|
||||
|
||||
|
||||
generate
|
||||
genvar i;
|
||||
logic [SLVNUM-1:0] cs_slv;
|
||||
logic [31 :0] dtemp[SLVNUM-1:0];
|
||||
|
||||
for(i=0;i<SLVNUM;i=i+1) begin: MAIN
|
||||
//generating device chip select signal
|
||||
//the largest 5bit addr is used to select among 32 SRAM
|
||||
assign cs_slv[i] = (mst.addr[24:20] == i );
|
||||
//generating device read/write signal
|
||||
if(SPIBUS_CMD_REG == 1) begin :CMD_REG
|
||||
sirv_gnrl_dffr #(20) rwaddr_dffr ({20{cs_slv[i]}} & mst.addr[19:0] ,slv[i].addr, clk, rst_n);
|
||||
sirv_gnrl_dffr #(32) wrdata_dffr ({32{cs_slv[i]}} & mst.din ,slv[i].din, clk, rst_n);
|
||||
sirv_gnrl_dffr #(1) wren_dffr (cs_slv[i] & mst.wren ,slv[i].wren, clk, rst_n);
|
||||
sirv_gnrl_dffr #(1) reen_dffr (cs_slv[i] & mst.rden ,slv[i].rden, clk, rst_n);
|
||||
end
|
||||
else begin :CMD_DONT_REG
|
||||
assign slv[i].addr = {20{cs_slv[i]}} & mst.addr[19:0];
|
||||
assign slv[i].wren = cs_slv[i] & mst.wren;
|
||||
assign slv[i].rden = cs_slv[i] & mst.rden;
|
||||
assign slv[i].din = {32{cs_slv[i]}} & mst.din;
|
||||
end
|
||||
|
||||
assign slv[i].wben = {4{cs_slv[i]}} & mst.wben;
|
||||
|
||||
if(i==0) begin: DETMP0
|
||||
assign dtemp[i] = (cs_slv[i]) ? slv[i].dout : 32'b0;
|
||||
end
|
||||
else begin: DETMP1_32
|
||||
assign dtemp[i] = (cs_slv[i]) ? slv[i].dout : dtemp[i-1];
|
||||
end
|
||||
end
|
||||
//read data from register
|
||||
if(SPIBUS_OUT_REG == 1) begin :OUT_REG
|
||||
wire [3:0] rden_dly;
|
||||
sirv_gnrl_dffr #(4) rddata_dffr ({rden_dly[2:0],mst.rden}, rden_dly[3:0], clk, rst_n);
|
||||
sirv_gnrl_dfflr #(32) rddata_dfflr (rden_dly[3],dtemp[SLVNUM-1], mst.dout, clk, rst_n);
|
||||
end
|
||||
else begin : OUT_DONT_REG
|
||||
assign mst.dout = dtemp[SLVNUM-1];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -0,0 +1,235 @@
|
|||
//+FHDR--------------------------------------------------------------------------------------------------------
|
||||
// Company:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// File Name : spi_pll.v
|
||||
// Department :
|
||||
// Author : PWY
|
||||
// Author's Tel :
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Relese History
|
||||
// Version Date Author Description
|
||||
// 0.1 2024-04-10 PWY Dedicated SPI interface for phase-locked loops (PLLs)
|
||||
// 0.2 2024-04-11 PWY Alter frame format
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Keywords :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Parameter
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Target Device:
|
||||
// Tool versions:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Reuse Issues
|
||||
// Reset Strategy:
|
||||
// Clock Domains:
|
||||
// Critical Timing:
|
||||
// Asynchronous I/F:
|
||||
// Synthesizable (y/n):
|
||||
// Other:
|
||||
//-FHDR--------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------Spi Frame-------------------------------------------------------------------------------------
|
||||
////MSB------------->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.....................................................>>>>>>>>------->LSB
|
||||
///|<-----------MSB 32 bits-------------------------->||<--Second 32-bit---->||<-------x 32-bit---->||<-------n 32-bit---->|
|
||||
// +-----++----------------------++------------++-----++---------------------++---------------------++---------------------+
|
||||
// | 31 || 30:6 || 5:1 || 0 || 31:0 || ...... || 31:0 |
|
||||
// +-----++----------------------++------------++-----++---------------------++---------------------++---------------------+
|
||||
// +-----++----------------------++------------++-----++---------------------++---------------------++---------------------+
|
||||
// | wnr || addr[24:0] || CHIPID ||resv || data[31:0] || ...... || data[31:0] |
|
||||
// +-----++----------------------++------------++-----++---------------------++---------------------++---------------------+
|
||||
//-----------------------------Spi Frame-------------------------------------------------------------------------------------
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module spi_pll (
|
||||
//reset active low
|
||||
input rst_n
|
||||
//cfg ID
|
||||
,input [4 :0] cfgid //ID number for the entire chip
|
||||
//SPI interface
|
||||
,input csn
|
||||
,input sclk
|
||||
,input mosi
|
||||
,output miso
|
||||
,output oen
|
||||
//SPI Select signal
|
||||
,output sel
|
||||
//regfile interface
|
||||
,output [31 :0] wrdata
|
||||
,output wren
|
||||
,output [7 :0] rwaddr
|
||||
,output rden
|
||||
,input [31 :0] rddata
|
||||
);
|
||||
|
||||
wire sel_w ;
|
||||
wire wnr ;
|
||||
wire [4 :0] addr_m5b ;
|
||||
wire [7 :0] addr_l8b ;
|
||||
//wire [4 :0] chipid ;
|
||||
wire [5 :0] chipid ;
|
||||
|
||||
wire data_valid ;
|
||||
//wire [31:0] rddata ;//////////////////////////////////////
|
||||
//reg rden_reg ;//////////////////////////////////////
|
||||
|
||||
//spi_rstn
|
||||
wire spi_rstn = rst_n & (~csn);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//bit count
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
wire [4:0] bit_cnt;
|
||||
//add_cnt
|
||||
wire add_cnt = ~csn;
|
||||
//end_cnt
|
||||
wire end_cnt = add_cnt & (bit_cnt == 5'd31);
|
||||
|
||||
|
||||
|
||||
wire [4:0] cnt_n = end_cnt ? 5'd0 :
|
||||
add_cnt ? bit_cnt + 5'b1 :
|
||||
bit_cnt ;
|
||||
|
||||
|
||||
sirv_gnrl_dffr #(5) bit_cnt_dffr (cnt_n, bit_cnt, sclk, spi_rstn);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//Determine whether the current input is an SPI command or data
|
||||
//Detect the falling edge on the most significant bit of the counter.
|
||||
//If a falling edge occurs, it indicates that the SPI frame has
|
||||
//entered the data transmission phase.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
wire bit_cnt_r;
|
||||
wire bit_cnt_falling = bit_cnt_r & ~bit_cnt[4];
|
||||
|
||||
sirv_gnrl_dffr #(1) bit_cnt_r_dffr (bit_cnt[4], bit_cnt_r, sclk, spi_rstn);
|
||||
|
||||
|
||||
//cmd_or_data:"High" represents data, "low" represents commands
|
||||
wire cmd_or_data;
|
||||
|
||||
sirv_gnrl_dfflr #(1) cmd_or_data_dfflr (bit_cnt_falling, 1'b1, cmd_or_data, sclk, spi_rstn);
|
||||
|
||||
wire second_falling;
|
||||
|
||||
sirv_gnrl_dfflr #(1) second_falling_dfflr (bit_cnt_falling & cmd_or_data, 1'b1, second_falling, sclk, spi_rstn);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//SPI data sample (Load mosi data)
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
generate
|
||||
genvar i;
|
||||
wire [31:0] recv_vld ;
|
||||
wire [31:0] mosi_reg ;
|
||||
for(i=0;i<32;i=i+1) begin: spi_pll_recv
|
||||
assign recv_vld[i] = add_cnt & (bit_cnt == i );
|
||||
sirv_gnrl_dfflr #(1) spi_din_dfflr (recv_vld[i], mosi, mosi_reg[31-i], sclk, spi_rstn);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
//addr valid
|
||||
wire addr_vaild = ~cmd_or_data & add_cnt & (bit_cnt == 5'd26);
|
||||
|
||||
//CMD Update
|
||||
sirv_gnrl_dfflr #(1) wnr_dfflr (addr_vaild, mosi_reg[31], wnr, sclk, spi_rstn);
|
||||
|
||||
//addr_m5b Update
|
||||
sirv_gnrl_dfflr #(5) addr_m5b_dfflr (addr_vaild, mosi_reg[30:26], addr_m5b, sclk, spi_rstn);
|
||||
|
||||
//addr_l8b Update
|
||||
sirv_gnrl_dfflr #(8) addr_l8b_dfflr (addr_vaild, mosi_reg[13:6], addr_l8b, sclk, spi_rstn);
|
||||
|
||||
//chipid Valid
|
||||
wire chipid_vld = ~cmd_or_data & add_cnt & (bit_cnt == 5'd30);
|
||||
//chipid Update
|
||||
sirv_gnrl_dfflrd #(6) chipid_dfflrd (6'b100000, chipid_vld, {1'b0, mosi_reg[5:2],mosi}, chipid, sclk, spi_rstn);
|
||||
|
||||
//sel_w
|
||||
assign sel_w = (addr_m5b == 5'b11111) & (chipid == {1'b0, cfgid});
|
||||
|
||||
|
||||
|
||||
//recv data valid
|
||||
assign data_valid = cmd_or_data & (bit_cnt == 5'd31);
|
||||
//assign data_valid = cmd_or_data & (bit_cnt == 5'd31);///////20240514
|
||||
//wren
|
||||
assign wren = data_valid & sel_w & ~wnr;
|
||||
|
||||
//rden
|
||||
//assign rden = add_cnt & (bit_cnt == 5'd30);/////////////////////////
|
||||
//assign rden = add_cnt & (bit_cnt == 5'd30) & sel_w;/////////////////////////20240514
|
||||
assign rden = add_cnt & (bit_cnt == 5'd30) & wnr;/////////////////////////20240604
|
||||
|
||||
wire rddata_update;
|
||||
sirv_gnrl_dffr #(1) rddata_update_dffr (rden, rddata_update, sclk, spi_rstn);
|
||||
|
||||
//wrdata
|
||||
assign wrdata = {mosi_reg[31:1],mosi};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Address generation for read and write operations
|
||||
//The address to be used for updating in the next
|
||||
//27 clock cycles in the read-write state
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
wire addr_update = ((wnr & cmd_or_data) | second_falling) & add_cnt & (bit_cnt == 5'd29);
|
||||
//wire addr_update = cmd_or_data & add_cnt & (bit_cnt == 5'd27);
|
||||
|
||||
wire [7:0] addr_c;
|
||||
|
||||
wire [7:0] addr_n = ~cmd_or_data ? addr_l8b :
|
||||
addr_update ? addr_c + 8'd4 :
|
||||
addr_c ;
|
||||
|
||||
sirv_gnrl_dffr #(8) addr_c_dffr (addr_n, addr_c, sclk, spi_rstn);
|
||||
|
||||
assign rwaddr = addr_c;
|
||||
|
||||
//sel
|
||||
assign sel = sel_w;
|
||||
|
||||
//oen
|
||||
//assign oen = ~(sel_w & wnr & ~csn);
|
||||
wire oen_w = ~(sel_w & wnr & ~csn);
|
||||
//assign oen = oen_w;
|
||||
sirv_gnrl_dffrs #(1) oen_dffrs (oen_w, oen, sclk, spi_rstn);
|
||||
//data output
|
||||
wire[31:0] miso_reg;
|
||||
wire[31:0] miso_wire;
|
||||
sirv_gnrl_dfflr #(32) miso_reg_dfflr (rddata_update, rddata, miso_reg, sclk, spi_rstn);
|
||||
assign miso_wire = miso_reg;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//SPI send data
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
generate
|
||||
genvar j;
|
||||
wire [31:0] send_vld ;
|
||||
wire [31:0] dtemp ;
|
||||
for(j=0;j<32;j=j+1) begin: spi_pll_send
|
||||
//assign send_vld[j] = (bit_cnt == ((j==31) ? 0 : (j+1)) );
|
||||
assign send_vld[j] = (bit_cnt == j );
|
||||
if(j==0) begin: dtemp0
|
||||
assign dtemp[j] = (send_vld[j]) ? miso_wire[31-j] : 1'b0;
|
||||
end
|
||||
else begin: dtemp1_32
|
||||
assign dtemp[j] = (send_vld[j]) ? miso_wire[31-j] : dtemp[j-1];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign miso = dtemp[31];
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
//+FHDR--------------------------------------------------------------------------------------------------------
|
||||
// Company:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// File Name : spi_top.v
|
||||
// Department :
|
||||
// Author : pwy
|
||||
// Author's Tel :
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Relese History
|
||||
// Version Date Author Description
|
||||
// 1.2 2024-04-02 pwy Integrate a digital module and two SPI modules with PLL
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Keywords :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Parameter
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Target Device:
|
||||
// Tool versions:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Reuse Issues
|
||||
// Reset Strategy:
|
||||
// Clock Domains:
|
||||
// Critical Timing:
|
||||
// Asynchronous I/F:
|
||||
// Synthesizable (y/n):
|
||||
// Other:
|
||||
//-FHDR--------------------------------------------------------------------------------------------------------
|
||||
|
||||
module spi_slave (
|
||||
//system port
|
||||
input clk // System Main Clock
|
||||
,input rst_n // Spi Reset active low
|
||||
//spi port
|
||||
,input sclk // Spi Clock
|
||||
,input csn // Spi Chip Select active low
|
||||
,input mosi // Spi Mosi
|
||||
,input [4 :0] cfgid
|
||||
,output miso // Spi Miso
|
||||
,output oen // Spi Miso output enable
|
||||
//connect pll
|
||||
,output [31 :0] pll_wrdata
|
||||
,output pll_wren
|
||||
,output [7 :0] pll_rwaddr
|
||||
,output pll_rden
|
||||
,input [31 :0] pll_rddata
|
||||
//connect system
|
||||
,output [31 :0] sys_wrdata
|
||||
,output sys_wren
|
||||
,output [24 :0] sys_rwaddr
|
||||
,output sys_rden
|
||||
,input [31 :0] sys_rddata
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// pll spi
|
||||
////////////////////////////////////////////////////////////////
|
||||
wire pll_miso ;
|
||||
wire pll_oen ;
|
||||
wire pll_sel ;
|
||||
|
||||
spi_pll U_spi_pll (
|
||||
.rst_n ( rst_n )
|
||||
,.cfgid ( cfgid )
|
||||
,.csn ( csn )
|
||||
,.sclk ( sclk )
|
||||
,.mosi ( mosi )
|
||||
,.miso ( pll_miso )
|
||||
,.oen ( pll_oen )
|
||||
,.sel ( pll_sel )
|
||||
,.wrdata ( pll_wrdata )
|
||||
,.wren ( pll_wren )
|
||||
,.rwaddr ( pll_rwaddr )
|
||||
,.rden ( pll_rden )
|
||||
,.rddata ( pll_rddata )
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//sys pll
|
||||
////////////////////////////////////////////////////////////////
|
||||
wire sys_miso ;
|
||||
wire sys_oen ;
|
||||
spi_sys U_spi_sys (
|
||||
.clk ( clk )
|
||||
,.rst_n ( rst_n )
|
||||
,.cfgid ( cfgid )
|
||||
,.sclk ( sclk )
|
||||
,.csn ( csn )
|
||||
,.mosi ( mosi )
|
||||
,.miso ( sys_miso )
|
||||
,.oen ( sys_oen )
|
||||
,.wrdata ( sys_wrdata )
|
||||
,.addr ( sys_rwaddr )
|
||||
,.wren ( sys_wren )
|
||||
,.rden ( sys_rden )
|
||||
,.rddata ( sys_rddata )
|
||||
);
|
||||
|
||||
assign miso = pll_sel ? pll_miso : sys_miso ;
|
||||
assign oen = pll_sel ? pll_oen : sys_oen ;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,292 @@
|
|||
//+FHDR--------------------------------------------------------------------------------------------------------
|
||||
// Company:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// File Name : spi_sys.v
|
||||
// Department :
|
||||
// Author : PWY
|
||||
// Author's Tel :
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Relese History
|
||||
// Version Date Author Description
|
||||
// 0.1 2024-04-13 PWY SPI BUS for System
|
||||
// 0.2 2024-06-24 PWY {spi_dout[31:0],1'b0} -> {spi_dout[30:0],1'b0}
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Keywords :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Parameter
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Target Device:
|
||||
// Tool versions:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Reuse Issues
|
||||
// Reset Strategy:
|
||||
// Clock Domains:
|
||||
// Critical Timing:
|
||||
// Asynchronous I/F:
|
||||
// Synthesizable (y/n):
|
||||
// Other:
|
||||
//-FHDR--------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------Spi Frame-------------------------------------------------------------------------------------
|
||||
////MSB------------->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>..............................................>>>>>>>>------->LSB
|
||||
///|<-----------MSB 32 bits------------------->||<---------Second 32-bit---->||<-------x 32-bit---->||<-------n 32-bit---->|
|
||||
// +-----++----------------------++------------++-----++---------------------++---------------------++---------------------+
|
||||
// | 31 || 30:6 || 5:1 || 0 || 31:0 || ...... || 31:0 |
|
||||
// +-----++----------------------++------------++-----++---------------------++---------------------++---------------------+
|
||||
// +-----++----------------------++------------++-----++---------------------++---------------------++---------------------+
|
||||
// | wnr || addr[24:0] || CHIPID ||resv || data[31:0] || ...... || data[31:0] |
|
||||
// +-----++----------------------++------------++-----++---------------------++---------------------++---------------------+
|
||||
//-----------------------------Spi Frame-------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
module spi_sys (
|
||||
//system port
|
||||
input clk // System Main Clock
|
||||
,input rst_n // Spi Reset active low
|
||||
//cfg ID
|
||||
,input [4 :0] cfgid //ID number for the entire chip
|
||||
//spi port
|
||||
,input sclk // Spi Clock
|
||||
,input csn // Spi Chip Select active low
|
||||
,input mosi // Spi Mosi
|
||||
,output miso // Spi Miso
|
||||
,output oen // Spi Miso output enable
|
||||
|
||||
,output [31:0] wrdata //write data to sram
|
||||
,output [24:0] addr //sram address
|
||||
,output wren //write enable sram
|
||||
,output rden //rden enable sram
|
||||
,input [31:0] rddata //read data from sram
|
||||
|
||||
);
|
||||
|
||||
localparam IDLE = 2'b00,
|
||||
RECVCMD = 2'b01,
|
||||
WRITE = 2'b10,
|
||||
READ = 2'b11;
|
||||
//-----------------------------------------------------------------------
|
||||
//SPI module reset processing
|
||||
//-----------------------------------------------------------------------
|
||||
//spi_rstn
|
||||
//wire spi_rstn;
|
||||
//assign spi_rstn = rst_n & (~csn);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//capture the sck
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
wire [2:0] sclk_reg;
|
||||
//sync sclk to the main clock using a 3-bits shift register
|
||||
sirv_gnrl_dffrs #(3) sclk_reg_dffrs ({sclk_reg[1:0],sclk}, sclk_reg, clk, rst_n);
|
||||
|
||||
//sclk's rising edges
|
||||
wire sclk_p = (sclk_reg[2:1] == 2'b01);
|
||||
|
||||
//sclk's falling edges
|
||||
//assign sclk_n = (sclk_reg[2:1] == 2'b10);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//capture the csn
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
wire [2:0] csn_reg;
|
||||
//sync csn to the main clock using a 2-bits shift register
|
||||
|
||||
sirv_gnrl_dffrs #(3) csn_reg_dffrs ({csn_reg[1:0],csn}, csn_reg, clk, rst_n);
|
||||
// csn is active low
|
||||
wire csn_active = ~csn_reg[1];
|
||||
|
||||
//csn's rising edges
|
||||
wire csn_p = (csn_reg[2:1] == 2'b01);
|
||||
|
||||
//csn's falling edges
|
||||
wire csn_n = (csn_reg[2:1] == 2'b10);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//capture the mosi
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
wire [1:0] mosi_reg;
|
||||
//sync mosi to the main clock using a 2-bits shift register
|
||||
|
||||
sirv_gnrl_dffr #(2) mosi_reg_dffr ({mosi_reg[0],mosi}, mosi_reg, clk, rst_n);
|
||||
//mosi_data
|
||||
wire mosi_data = mosi_reg[1];
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//cnt
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
wire [4:0] cnt_c;
|
||||
//add_cnt
|
||||
wire add_cnt = sclk_p && csn_active;
|
||||
//end_cnt
|
||||
wire end_cnt = (add_cnt && (cnt_c == 5'd31)) | csn_p;
|
||||
|
||||
wire [4:0] cnt_n = end_cnt ? 5'h0 :
|
||||
add_cnt ? cnt_c + 5'b1 :
|
||||
cnt_c ;
|
||||
|
||||
|
||||
sirv_gnrl_dffr #(5) cnt_c_dffr (cnt_n, cnt_c, clk, rst_n);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//SPI data sample
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
generate
|
||||
genvar i;
|
||||
wire [31:0] recv_vld ;
|
||||
wire [31:0] spi_din ;
|
||||
for(i=0;i<32;i=i+1) begin: spi_sys_recv
|
||||
assign recv_vld[i] = add_cnt & (cnt_c == i );
|
||||
sirv_gnrl_dfflr #(1) spi_din_dfflr (recv_vld[i], mosi_data, spi_din[31-i], clk, rst_n);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
wire [1:0] state_c;
|
||||
wire [1:0] state_n;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//init_addr capture
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
wire [24:0] initaddr;
|
||||
wire initaddr_vld = (state_c == RECVCMD ) & add_cnt && (cnt_c == 5'd26);
|
||||
wire [1:0] initaddr_vld_r;
|
||||
sirv_gnrl_dffr #(2) initaddr_vld_r_dffr ({initaddr_vld_r[0],initaddr_vld}, initaddr_vld_r, clk, rst_n);
|
||||
|
||||
sirv_gnrl_dfflr #(25) initaddr_dfflr (initaddr_vld_r[0], spi_din[30:6], initaddr, clk, rst_n);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//CMD capture
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
wire cmd ;
|
||||
sirv_gnrl_dfflr #(1) cmd_dfflr ( initaddr_vld_r[0], spi_din[31], cmd, clk, rst_n);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//CHIPID capture
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
wire [4:0] chipid;
|
||||
wire [1:0] chipid_vld_r;
|
||||
wire chipid_vld = (state_c == RECVCMD ) & add_cnt & (cnt_c == 5'd30);
|
||||
//register cmd_vld to align it with cmd
|
||||
sirv_gnrl_dffr #(2) chipid_vld_r_dffr ({chipid_vld_r[0],chipid_vld}, chipid_vld_r, clk, rst_n);
|
||||
|
||||
sirv_gnrl_dfflr #(5) chipid_dfflr (chipid_vld_r[0], spi_din[5:1], chipid, clk, rst_n);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//ID matching determination
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
wire chipid_match = (chipid == cfgid);
|
||||
wire chipid_dismatch = (chipid != cfgid);
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//SPI Module State Machine
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
//Generating jump conditions for state machines
|
||||
wire ilde2recvcmd = (state_c == IDLE ) && csn_active && csn_n ;
|
||||
wire recvcmd2ilde = (state_c == RECVCMD ) && chipid_dismatch & end_cnt;
|
||||
wire recvcmd2write = (state_c == RECVCMD ) && chipid_match && ~cmd & end_cnt;
|
||||
wire recvcmd2read = (state_c == RECVCMD ) && chipid_match && cmd & end_cnt;
|
||||
wire write2idle = (state_c == WRITE ) && csn_p;
|
||||
wire read2idle = (state_c == READ ) && csn_p;
|
||||
|
||||
//The first section of the state machine
|
||||
//state_c
|
||||
sirv_gnrl_dffr #(2) state_c_dffr (state_n, state_c, clk, rst_n);
|
||||
|
||||
//state_n
|
||||
assign state_n = ((state_c == IDLE ) && ilde2recvcmd ) ? RECVCMD :
|
||||
((state_c == RECVCMD ) && recvcmd2ilde ) ? IDLE :
|
||||
((state_c == RECVCMD ) && recvcmd2write ) ? WRITE :
|
||||
((state_c == RECVCMD ) && recvcmd2read ) ? READ :
|
||||
((state_c == WRITE ) && write2idle ) ? IDLE :
|
||||
((state_c == READ ) && read2idle ) ? IDLE :
|
||||
state_c ;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Address generation for read and write operations
|
||||
//The address to be used for updating in the next
|
||||
//27 clock cycles in the read-write state
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
wire second_falling;
|
||||
wire second_falling_w = (state_c == WRITE);
|
||||
sirv_gnrl_dfflr #(1) second_falling_dfflr (end_cnt ,second_falling_w, second_falling, clk, rst_n);
|
||||
|
||||
wire addr_update = ((state_c == READ) | ((state_c == WRITE) & second_falling)) & add_cnt & (cnt_c == 5'd27);
|
||||
wire [24:0] addr_c;
|
||||
|
||||
wire [24:0] addr_n = ilde2recvcmd ? 25'd0 :
|
||||
initaddr_vld_r[1] ? initaddr :
|
||||
addr_update ? addr_c + 25'd4 :
|
||||
addr_c ;
|
||||
|
||||
sirv_gnrl_dffr #(25) addr_c_dffr (addr_n, addr_c, clk, rst_n);
|
||||
|
||||
assign addr = addr_c;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Write data and write signals generation
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
wire wren_r;
|
||||
|
||||
wire wren_w = (state_c == WRITE) & add_cnt & (cnt_c == 5'd31);
|
||||
//wdata
|
||||
sirv_gnrl_dfflr #(32) wrdata_dfflr (wren_r, spi_din[31:0], wrdata, clk, rst_n);
|
||||
//wren_r
|
||||
|
||||
sirv_gnrl_dffr #(1) wren_r_dffr (wren_w, wren_r, clk, rst_n);
|
||||
|
||||
//wren
|
||||
sirv_gnrl_dffr #(1) wren_dffr (wren_r, wren, clk, rst_n);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//read signals generation
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
wire rden_w = chipid_match & cmd & add_cnt & (cnt_c == 5'd28);
|
||||
sirv_gnrl_dffr #(1) rden_dffr (rden_w, rden, clk, rst_n);
|
||||
|
||||
//Read data register
|
||||
wire rddata_vld = cmd & add_cnt & (cnt_c == 5'd30);
|
||||
wire [31:0] rddata_reg;
|
||||
sirv_gnrl_dfflr #(32) rddata_reg_dfflr (rddata_vld, rddata[31:0], rddata_reg, clk, rst_n);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//SPI send data update
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
wire [31:0] spi_dout ;
|
||||
wire update_flag = cmd & add_cnt & (cnt_c == 5'd31);
|
||||
|
||||
wire [31:0] rddata_sr = update_flag ? rddata_reg[31:0] :
|
||||
((state_c == READ) & add_cnt) ? {spi_dout[30:0],1'b0} : //M 2024-06-24
|
||||
spi_dout ;
|
||||
|
||||
sirv_gnrl_dffr #(32) spi_dout_dffr (rddata_sr, spi_dout, clk, rst_n);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//SPI send data
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
assign miso = spi_dout[31];
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//SPI output enable
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
sirv_gnrl_dffrs #(1) oen_dffr (~(state_c == READ), oen, clk, rst_n);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,716 @@
|
|||
//+FHDR--------------------------------------------------------------------------------------------------------
|
||||
// Company:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// File Name : ssytem_regfile.v
|
||||
// Department :
|
||||
// Author : PWY
|
||||
// Author's Tel :
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Relese History
|
||||
// Version Date Author Description
|
||||
// 1.0 2026-03-01 PWY
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Keywords :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Parameter
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Target Device:
|
||||
// Tool versions:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Reuse Issues
|
||||
// Reset Strategy:
|
||||
// Clock Domains:
|
||||
// Critical Timing:
|
||||
// Asynchronous I/F:
|
||||
// Synthesizable (y/n):
|
||||
// Other:
|
||||
//-FHDR--------------------------------------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// -- Register address offset macros
|
||||
// -----------------------------------------------------------
|
||||
//Identity Register
|
||||
`define IDR 16'h00
|
||||
//Vendor Code Register
|
||||
`define VIDR 16'h04
|
||||
//RTL Freeze Date Register
|
||||
`define DATER 16'h08
|
||||
//Version Register
|
||||
`define VERR 16'h0C
|
||||
//Wirte And Read Test Register
|
||||
`define TESTR 16'h10
|
||||
//Status Register
|
||||
`define ISR 16'h14
|
||||
//Soft Reset Time Register
|
||||
`define SFRTR 16'h18
|
||||
//Soft Reset Register
|
||||
`define SFRR 16'h1C
|
||||
//Sync Cntrl Register
|
||||
`define SYNCR 16'h20
|
||||
//Ramp Ctrl Register
|
||||
`define RAMPCTR 16'h24
|
||||
//Ramp IFS Register
|
||||
`define RAMPIFSR 16'h28
|
||||
//Data Out Select Register
|
||||
`define DOSELR 16'h2C
|
||||
//Lvds Force Train Register
|
||||
`define LVDSFTR 16'h30
|
||||
//Lvds Tap Force Register
|
||||
`define LVDSTFR 16'h34
|
||||
//Lvds Tap Step Register
|
||||
`define LVDSTSR 16'h38
|
||||
//Lvds Train Threshold Register
|
||||
`define LVDSTHR 16'h3C
|
||||
//Lvds Tap Adj Mask Register
|
||||
`define LVDSTAMR 16'h40
|
||||
//Lvds Descram Enable Register
|
||||
`define LVDSDSER 16'h44
|
||||
//Lvds Train Always On Register
|
||||
`define LVDSTAOR 16'h48
|
||||
//Lvds Status Register
|
||||
`define LVDSSR 16'h4C
|
||||
//Lvds Frame Success Count Register
|
||||
`define LVDSFSCR 16'h50
|
||||
//Lvds CRC Error Count Register
|
||||
`define LVDSCECR 16'h54
|
||||
//Lvds Frame Status Register
|
||||
`define LVDSFSTR 16'h58
|
||||
//Lvds Train Status Register
|
||||
`define LVDSTSTR 16'h5C
|
||||
|
||||
//Interrupt Mask Register
|
||||
//[31 :6] --> Reserved
|
||||
//[5 ] --> crc_error Interrupt Mask
|
||||
//[4 ] --> phase_adj_req Interrupt Mask
|
||||
//[3 ] --> train_ready Interrupt Mask
|
||||
//[2 ] --> link_down Interrupt Mask
|
||||
//[1 ] --> cmd_fifo_empty Interrupt Mask
|
||||
//[0 ] --> cmd_fifo_full Interrupt Mask
|
||||
`define IMR 16'h60
|
||||
|
||||
//Interrupt Mask Register
|
||||
//[31 :6] --> Reserved
|
||||
//[5 ] --> crc_error Masked Interrupt Status
|
||||
//[4 ] --> phase_adj_req Masked Interrupt Status
|
||||
//[3 ] --> train_ready Masked Interrupt Status
|
||||
//[2 ] --> link_down Masked Interrupt Status
|
||||
//[1 ] --> cmd_fifo_empty Masked Interrupt Status
|
||||
//[0 ] --> cmd_fifo_full Masked Interrupt Status
|
||||
`define MISR 16'h64
|
||||
|
||||
module systemregfile # (
|
||||
parameter CHIPCODE = 32'hDA400801 // 32'hDA400801:DA4008-01
|
||||
,parameter MFDATE = 32'h20260510 // The production date is May 10, 2026
|
||||
)(
|
||||
//system port
|
||||
input clk // System Main Clock
|
||||
,input rst_n // Spi Reset active low
|
||||
//rw op port
|
||||
,input [31 :0] wrdata // write data
|
||||
,input wren // write enable
|
||||
,input [15 :0] rwaddr // read & write address
|
||||
,input rden // read enable
|
||||
,output [31 :0] rddata // read data
|
||||
//irq
|
||||
,output irq
|
||||
//Status input
|
||||
,input cmd_fifo_full
|
||||
,input cmd_fifo_empty
|
||||
,input [2 :0] awg_status
|
||||
,input awg_busy
|
||||
//Soft Reset out
|
||||
,output sys_soft_rstn
|
||||
//Data Out Select port
|
||||
,output [0 :0] dout_sel //1'b0: Sram Data; 1'b1: Ramp Data;
|
||||
//SYNC Ctrl
|
||||
,output [15 :0] sync_delay
|
||||
,output int_sync
|
||||
,output int_sync_en
|
||||
,output sync_oen
|
||||
//Ramp Cntrl Signals
|
||||
,output ramp_en //ramp_en = dout_sel[0];
|
||||
,output [31 :0] ramp_ifs
|
||||
,output [7 :0] ramp_step
|
||||
,output ramp_fixed
|
||||
,output [7 :0] ramp_fixed_value
|
||||
//LVDS
|
||||
,output force_train
|
||||
,output tap_force
|
||||
,output [2 :0] tap_step
|
||||
,output [2 :0] tap_adj_mask
|
||||
,output [19 :0] train_threshold
|
||||
,output descram_en
|
||||
,output always_on
|
||||
,input link_down
|
||||
,input train_ready
|
||||
,input crc_error
|
||||
,input phase_adj_req
|
||||
,input [2 :0] phase_tap
|
||||
,input [31 :0] frame_success_cnt
|
||||
,input [31 :0] crc_err_cnt
|
||||
,input prefilling
|
||||
,input [31 :0] train_status
|
||||
,input [31 :0] frame_status
|
||||
);
|
||||
|
||||
localparam L = 1'b0,
|
||||
H = 1'b1;
|
||||
|
||||
localparam IDRD = CHIPCODE;
|
||||
localparam VIDRD = 32'h58445500;
|
||||
localparam DATERD = MFDATE;
|
||||
localparam VERSION = 32'h00000001;
|
||||
localparam TESTRD = 32'h01234567;
|
||||
// ------------------------------------------------------
|
||||
// -- Register enable (select) wires
|
||||
// ------------------------------------------------------
|
||||
wire idren ; // IDR select
|
||||
wire vidren ; // VIDR select
|
||||
wire dateren ; // DATER select
|
||||
wire verren ; // VERR select
|
||||
wire testren ; // TESTR select
|
||||
wire isren ; // ISR select
|
||||
wire sfrtren ; // MISR select
|
||||
wire sfrren ; // SFRTR select
|
||||
wire syncren ; // SFRR select
|
||||
wire rampctren ; // RAMPCTR select
|
||||
wire rampifsren ; // RAMPIFSR select
|
||||
wire doselren ; // DOSELR select
|
||||
wire lvdsftren ; // LVDSFTR select
|
||||
wire lvdstfren ; // LVDSTFR select
|
||||
wire lvdstsren ; // LVDSTSR select
|
||||
wire lvdsthren ; // LVDSTHR select
|
||||
wire lvdssren ; // LVDSSR select
|
||||
wire lvdsfcsren ; // LVDSFSCR select
|
||||
wire lvdscecren ; // LVDSCECR select
|
||||
wire lvdstamren ; // LVDSTAMR select
|
||||
wire lvdsdseren ; // LVDSDSER select
|
||||
wire lvdstaoren ; // LVDSTAOR select
|
||||
wire lvdsfstren ; // LVDSFSTR select
|
||||
wire lvdststren ; // LVDSTSTR select
|
||||
wire imren ; // IMR select
|
||||
wire misren ; // MISR select
|
||||
// ------------------------------------------------------
|
||||
// -- Register write enable wires
|
||||
// ------------------------------------------------------
|
||||
wire testrwe ; // testr write enable
|
||||
wire sfrtrwe ; // sfrtr write enable
|
||||
wire sfrrwe ; // sfrr write enable
|
||||
wire syncrwe ; // syncr write enable
|
||||
wire rampctrwe ; // RAMPCTR write enable
|
||||
wire rampifsrwe ; // RAMPIFSR write enable
|
||||
wire doselrwe ; // DOSELR write enable
|
||||
wire lvdsftrwe ; // LVDSFTR write enable
|
||||
wire lvdsatrwe ; // LVDSATR write enable
|
||||
wire lvdstsrwe ; // LVDSTSR write enable
|
||||
wire lvdsthrwe ; // LVDSTHR write enable
|
||||
wire lvdsdserwe ; // LVDSDSER write enable
|
||||
wire lvdstaorwe ; // LVDSTAOR write enable
|
||||
wire imrwe ; // IMR write enable
|
||||
// ------------------------------------------------------
|
||||
// -- Misc wires
|
||||
// ------------------------------------------------------
|
||||
wire [5 :0] irisr ; // original status wire
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Misc Registers
|
||||
// ------------------------------------------------------
|
||||
wire [31 :0] testr ;
|
||||
wire [5 :0] isr ;
|
||||
wire [31 :0] sfrtr ;
|
||||
wire [0 :0] sfrr ;
|
||||
wire [18 :0] syncr ;
|
||||
wire [23 :0] rampctr ;
|
||||
wire [31 :0] rampifsr ;
|
||||
wire [0 :0] doselr ;
|
||||
|
||||
wire [0 :0] lvdsftr ;
|
||||
wire [0 :0] lvdsatr ;
|
||||
wire [2 :0] lvdstsr ;
|
||||
wire [19 :0] lvdsthr ;
|
||||
wire [7 :0] lvdssr ;
|
||||
wire [31 :0] lvdsfcsr ;
|
||||
wire [31 :0] lvdscecr ;
|
||||
wire [2 :0] lvdstamr ;
|
||||
wire [0 :0] lvdsdser ;
|
||||
wire [0 :0] lvdstaor ;
|
||||
wire [31 :0] lvdsfstr ;
|
||||
wire [31 :0] lvdststr ;
|
||||
wire [5 :0] imr ;
|
||||
wire [5 :0] misr ;
|
||||
|
||||
reg [31 :0] rddata_reg ;
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Address decoder
|
||||
//
|
||||
// Decodes the register address offset input(reg_addr)
|
||||
// to produce enable (select) signals for each of the
|
||||
// SW-registers in the macrocell. The reg_addr input
|
||||
// is bits [8:0] of the paddr bus.
|
||||
// ------------------------------------------------------
|
||||
assign idren = (rwaddr[15:2] == `IDR >> 2) ? 1'b1 : 1'b0;
|
||||
assign vidren = (rwaddr[15:2] == `VIDR >> 2) ? 1'b1 : 1'b0;
|
||||
assign dateren = (rwaddr[15:2] == `DATER >> 2) ? 1'b1 : 1'b0;
|
||||
assign verren = (rwaddr[15:2] == `VERR >> 2) ? 1'b1 : 1'b0;
|
||||
assign testren = (rwaddr[15:2] == `TESTR >> 2) ? 1'b1 : 1'b0;
|
||||
assign isren = (rwaddr[15:2] == `ISR >> 2) ? 1'b1 : 1'b0;
|
||||
assign sfrtren = (rwaddr[15:2] == `SFRTR >> 2) ? 1'b1 : 1'b0;
|
||||
assign sfrren = (rwaddr[15:2] == `SFRR >> 2) ? 1'b1 : 1'b0;
|
||||
assign syncren = (rwaddr[15:2] == `SYNCR >> 2) ? 1'b1 : 1'b0;
|
||||
assign rampctren = (rwaddr[15:2] == `RAMPCTR >> 2) ? 1'b1 : 1'b0;
|
||||
assign rampifsren = (rwaddr[15:2] == `RAMPIFSR >> 2) ? 1'b1 : 1'b0;
|
||||
assign doselren = (rwaddr[15:2] == `DOSELR >> 2) ? 1'b1 : 1'b0;
|
||||
assign lvdsftren = (rwaddr[15:2] == `LVDSFTR >> 2) ? 1'b1 : 1'b0;
|
||||
assign lvdstfren = (rwaddr[15:2] == `LVDSTFR >> 2) ? 1'b1 : 1'b0;
|
||||
assign lvdstsren = (rwaddr[15:2] == `LVDSTSR >> 2) ? 1'b1 : 1'b0;
|
||||
assign lvdsthren = (rwaddr[15:2] == `LVDSTHR >> 2) ? 1'b1 : 1'b0;
|
||||
assign lvdssren = (rwaddr[15:2] == `LVDSSR >> 2) ? 1'b1 : 1'b0;
|
||||
assign lvdsfcsren = (rwaddr[15:2] == `LVDSFSCR >> 2) ? 1'b1 : 1'b0;
|
||||
assign lvdscecren = (rwaddr[15:2] == `LVDSCECR >> 2) ? 1'b1 : 1'b0;
|
||||
assign lvdstamren = (rwaddr[15:2] == `LVDSTAMR >> 2) ? 1'b1 : 1'b0;
|
||||
assign lvdsdseren = (rwaddr[15:2] == `LVDSDSER >> 2) ? 1'b1 : 1'b0;
|
||||
assign lvdstaoren = (rwaddr[15:2] == `LVDSTAOR >> 2) ? 1'b1 : 1'b0;
|
||||
assign lvdsfstren = (rwaddr[15:2] == `LVDSFSTR >> 2) ? 1'b1 : 1'b0;
|
||||
assign lvdststren = (rwaddr[15:2] == `LVDSTSTR >> 2) ? 1'b1 : 1'b0;
|
||||
assign imren = (rwaddr[15:2] == `IMR >> 2) ? 1'b1 : 1'b0;
|
||||
assign misren = (rwaddr[15:2] == `MISR >> 2) ? 1'b1 : 1'b0;
|
||||
// ------------------------------------------------------
|
||||
// -- Write enable signals
|
||||
//
|
||||
// Write enable signals for writable SW-registers.
|
||||
// The write enable for each register is the ANDed
|
||||
// result of the register enable and the input reg_wren
|
||||
// ------------------------------------------------------
|
||||
assign testrwe = testren & wren;
|
||||
assign sfrtrwe = sfrtren & wren;
|
||||
assign sfrrwe = sfrren & wren;
|
||||
assign syncrwe = syncren & wren;
|
||||
assign rampctrwe = rampctren & wren;
|
||||
assign rampifsrwe = rampifsren & wren;
|
||||
assign doselrwe = doselren & wren;
|
||||
assign lvdsftrwe = lvdsftren & wren;
|
||||
assign lvdstfrwe = lvdstfren & wren;
|
||||
assign vdstsrwe = lvdstsren & wren;
|
||||
assign lvdsthrwe = lvdsthren & wren;
|
||||
assign lvdstamrwe = lvdstamren & wren;
|
||||
assign lvdsdserwe = lvdstamren & wren;
|
||||
|
||||
assign imrwe = imren & wren;
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- testr Register
|
||||
//
|
||||
// Write testr for 'TESTR' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> testr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) testr_dfflrd (TESTRD, testrwe, wrdata[31:0], testr, clk, rst_n);
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Soft Reset Count Register
|
||||
//
|
||||
// Write Soft Reset Count for 'sfrtcr' : 6-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> sfrtcr,default value 32'd300
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(32) sfrtr_dfflrd (32'd1, sfrtrwe, wrdata[31:0], sfrtr, clk, rst_n);/////////////////////////////sfrtcr-->sfrtr
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- SYNC Contrl Register
|
||||
//
|
||||
//
|
||||
// [17 ] --> sync_oen ,default value 1'b0
|
||||
// [17 ] --> int_sync_en,default value 1'b0
|
||||
// [16 ] --> int_sync ,default value 1'b0
|
||||
// [15:0] --> sync_delay ,default value 16'd0
|
||||
// ------------------------------------------------------
|
||||
//sirv_gnrl_dfflr #(18) syncr_dfflr (syncrwe, wrdata[17:0], syncr, clk, rst_n);
|
||||
// sirv_gnrl_dfflr #(17) syncr_dfflr (syncrwe, {syncrwe,wrdata[15:0]}, syncr, clk, rst_n); //pwy-20250808
|
||||
sirv_gnrl_dfflrd #(16) syncr_dfflrd (16'd1, syncrwe, wrdata[15:0], syncr[15:0], clk, rst_n); //pwy-20250808
|
||||
sirv_gnrl_dffr #(1) syncr16_dffr (syncrwe & wrdata[16], syncr[16], clk, rst_n); //pwy-20250808
|
||||
sirv_gnrl_dfflrd #(1) syncr16_dfflrd (1'b1, syncrwe, wrdata[17], syncr[17], clk, rst_n); //pwy-20250808
|
||||
sirv_gnrl_dfflrd #(1) sync_oen_dfflrd (1'b0, syncrwe, wrdata[18], syncr[18], clk, rst_n); //pwy-20260303
|
||||
// ------------------------------------------------------
|
||||
// -- rampctr register
|
||||
//
|
||||
// Write rampctr for 'RAMPCTR' : 24-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [23:0] --> rampctr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflr #(24) rampctr_dfflrs (rampctrwe, wrdata[23:0], rampctr, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- rampifsr register
|
||||
//
|
||||
// Write rampifsr for 'rampifsr' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> ramp_ifs
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflr #(32) ramp_ifs_dfflrs (rampifsrwe, wrdata[31:0], rampifsr, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- doselr register
|
||||
//
|
||||
// Write doselr for 'DOSELR' : 1-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [0:0] --> doselr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflr #(1) doselr_dfflrs (doselrwe, wrdata[0], doselr, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- lvdsftr Register
|
||||
//
|
||||
// Write lvdsftr for 'LVDSFTR' : 1-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [0:0] --> lvdsftr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dffr #(1) lvdsftr_dffr (lvdsftrwe & wrdata[0], lvdsftr, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- lvdstfr register
|
||||
//
|
||||
// Write lvdstfr for 'LVDSTFR' : 1-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [0:0] --> lvdstfr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflr #(1) lvdstfr_dfflrs (lvdstfrwe, wrdata[0], lvdstfr, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- lvdstsr register
|
||||
//
|
||||
// Write lvdstsr for 'LVDSTSR' : 1-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [2:0] --> lvdstsr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(3) lvdstsr_dfflrd (3'd1, lvdstsrwe, wrdata[2:0], lvdstsr, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- lvdsthr register
|
||||
//
|
||||
// Write lvdsthr for 'LVDSTHR' : 20-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [19:0] --> lvdsthr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(20) lvdsthr_dfflrd (20'd100, lvdsthrwe, wrdata[19:0], lvdsthr, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- lvdstamr register
|
||||
//
|
||||
// Write lvdsfcsr for 'LVDSTAMR' : 3-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [2:0] --> lvdstamr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(3) lvdstamr_dfflrd (3'b111, lvdstamrwe, wrdata[2:0], lvdstamr, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- lvdsdser register
|
||||
//
|
||||
// Write lvdsfcsr for 'LVDSDSER' : 1-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [0:0] --> lvdsdser
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(1) lvdsdser_dfflrd (1'b1, lvdsdserwe, wrdata[0], lvdsdser, clk, rst_n);
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- lvdstaor register
|
||||
//
|
||||
// Write lvdstaor for 'LVDSTAOR' : 1-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [0:0] --> lvdstaor
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dfflrd #(1) lvdstaor_dfflrd (1'b1, lvdstaorwe, wrdata[0], lvdstaor, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- lvdssr register
|
||||
//
|
||||
// Write lvdssr for 'LVDSSR' : 8-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [7:0] --> lvdssr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dffr #(8) llvdssr_dffr ({ link_down ,train_ready ,crc_error ,
|
||||
phase_adj_req ,phase_tap[2:0] ,
|
||||
prefilling }, lvdssr, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- lvdsfcsr register
|
||||
//
|
||||
// Write lvdsfcsr for 'LVDSFSCR' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> lvdsfcsr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dffr #(32) lvdsfcsr_dffr (frame_success_cnt, lvdsfcsr, clk, rst_n);
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- lvdscecr register
|
||||
//
|
||||
// Write lvdscecr for 'LVDSCECR' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> lvdscecr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dffr #(32) lvdscecr_dffr (crc_err_cnt, lvdscecr, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- lvdsfstr register
|
||||
//
|
||||
// Write lvdsfstr for 'LVDSFSR' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> lvdsfstr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dffr #(32) lvdsfstr_dffr (frame_status, lvdsfstr, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- lvdststr register
|
||||
//
|
||||
// Write lvdststr for 'LVDTFSR' : 32-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [31:0] --> lvdststr
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dffr #(32) lvdststr_dffr (train_status, lvdststr, clk, rst_n);
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------
|
||||
// -- interrupt Mask Register
|
||||
//
|
||||
// Write interrupt Mask for 'imr' : 6-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
//Interrupt Mask Register
|
||||
//[31 :6] --> Reserved
|
||||
//[5 ] --> crc_error Interrupt Mask
|
||||
//[4 ] --> phase_adj_req Interrupt Mask
|
||||
//[3 ] --> train_ready Interrupt Mask
|
||||
//[2 ] --> link_down Interrupt Mask
|
||||
//[1 ] --> cmd_fifo_empty Interrupt Mask
|
||||
//[0 ] --> cmd_fifo_full Interrupt Mask
|
||||
// ---------------------------------------------------------------------------------------------------
|
||||
sirv_gnrl_dfflr #(6) imr_dfflr (imrwe, wrdata[5:0], imr, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- soft reset count
|
||||
// ------------------------------------------------------
|
||||
|
||||
wire [31:0] cnt_c;
|
||||
wire sys_soft_rstn_r;
|
||||
wire add_cnt = (sys_soft_rstn_r == L) ;
|
||||
|
||||
wire end_cnt = add_cnt & (cnt_c == sfrtr-1);
|
||||
|
||||
wire [31:0] cnt_n = end_cnt ? 32'h0 :
|
||||
add_cnt ? cnt_c + 1'b1 :
|
||||
cnt_c ;
|
||||
|
||||
|
||||
sirv_gnrl_dffr #(32) cnt_c_dffr (cnt_n, cnt_c, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Soft Reset Register
|
||||
//
|
||||
// Write Soft Reset for 'sfrtr' : 1-bit register
|
||||
// Register is split into the following bit fields
|
||||
//
|
||||
// [16'h001C] --> System Soft Reset ,low active
|
||||
// ------------------------------------------------------
|
||||
|
||||
//sys_soft_rstn_r
|
||||
wire sys_soft_rstn_en = end_cnt | sfrrwe;
|
||||
wire sys_soft_rstn_w = end_cnt ? 1'b1 :
|
||||
sfrrwe ? 1'b0 :
|
||||
1'b1 ;
|
||||
sirv_gnrl_dfflrs #(1) sys_soft_rstn_r_dffls (sys_soft_rstn_en, sys_soft_rstn_w, sys_soft_rstn_r, clk, rst_n);
|
||||
|
||||
assign sys_soft_rstn = sys_soft_rstn_r;
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Read data mux
|
||||
//
|
||||
// -- The data from the selected register is
|
||||
// -- placed on a zero-padded 32-bit read data bus.
|
||||
// ------------------------------------------------------
|
||||
always @(*) begin : RDDATA_PROC
|
||||
rddata_reg = {32{1'b0}};
|
||||
if(idren == H) rddata_reg[31:0] = IDRD ;
|
||||
if(vidren == H) rddata_reg[31:0] = VIDRD ;
|
||||
if(dateren == H) rddata_reg[31:0] = DATERD ;
|
||||
if(verren == H) rddata_reg[31:0] = VERSION ;
|
||||
if(testren == H) rddata_reg[31:0] = testr ;
|
||||
if(isren == H) rddata_reg[31:0] = isr ;
|
||||
if(sfrtren == H) rddata_reg[31:0] = sfrtr ;
|
||||
if(syncren == H) rddata_reg[18:0] = syncr ;
|
||||
if(rampctren == H) rddata_reg[23:0] = rampctr ;
|
||||
if(rampifsren == H) rddata_reg[31:0] = rampifsr ;
|
||||
if(doselren == H) rddata_reg[0 :0] = doselr ;
|
||||
if(lvdsftren == H) rddata_reg[0 :0] = lvdsftr ;
|
||||
if(lvdstfren == H) rddata_reg[0 :0] = lvdstfr ;
|
||||
if(lvdstsren == H) rddata_reg[2 :0] = lvdstsr ;
|
||||
if(lvdsthren == H) rddata_reg[19:0] = lvdsthr ;
|
||||
if(lvdssren == H) rddata_reg[7 :0] = lvdssr ;
|
||||
if(lvdstamren == H) rddata_reg[2 :0] = lvdstamr ;
|
||||
if(lvdsfcsren == H) rddata_reg[31:0] = lvdsfcsr ;
|
||||
if(lvdscecren == H) rddata_reg[31:0] = lvdscecr ;
|
||||
if(lvdsdseren == H) rddata_reg[0 :0] = lvdsdser ;
|
||||
if(lvdstaoren == H) rddata_reg[0 :0] = lvdstaor ;
|
||||
if(lvdsfstren == H) rddata_reg[31:0] = lvdsfstr ;
|
||||
if(lvdststren == H) rddata_reg[31:0] = lvdststr ;
|
||||
if(imren == H) rddata_reg[5 :0] = imr ;
|
||||
if(misren == H) rddata_reg[5 :0] = misr ;
|
||||
end
|
||||
|
||||
//rddata
|
||||
sirv_gnrl_dfflr #(32) rddata_dfflr (rden, rddata_reg, rddata, clk, rst_n);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- status
|
||||
// ------------------------------------------------------
|
||||
//read misr clear interrupts
|
||||
wire icr = (misren) && rden;
|
||||
|
||||
//train_ready
|
||||
wire train_ready_r;
|
||||
wire train_ready_en = icr | train_ready;
|
||||
wire train_ready_w = ~icr | train_ready;
|
||||
sirv_gnrl_dfflr #(1) train_ready_r_dfflr (train_ready_en, train_ready_w, train_ready_r, clk, rst_n);
|
||||
|
||||
//crc_error
|
||||
wire crc_error_r;
|
||||
wire crc_error_en = icr | crc_error;
|
||||
wire crc_error_w = ~icr | crc_error;
|
||||
sirv_gnrl_dfflr #(1) crc_error_r_dfflr (crc_error_en, crc_error_w, crc_error_r, clk, rst_n);
|
||||
|
||||
//phase_adj_req
|
||||
wire phase_adj_req_r;
|
||||
wire phase_adj_req_en = icr | phase_adj_req;
|
||||
wire phase_adj_req_w = ~icr | phase_adj_req;
|
||||
sirv_gnrl_dfflr #(1) cphase_adj_req_r_dfflr (phase_adj_req_en, phase_adj_req_w, phase_adj_req_r, clk, rst_n);
|
||||
|
||||
//link_down
|
||||
wire link_down_r;
|
||||
wire link_down_en = icr | link_down;
|
||||
wire link_down_w = ~icr | link_down;
|
||||
sirv_gnrl_dfflr #(1) link_down_r_dfflr (link_down_en, link_down_w, link_down_r, clk, rst_n);
|
||||
|
||||
//cmd_fifo_full
|
||||
wire cmd_fifo_full_r;
|
||||
wire cmd_fifo_full_en = icr | cmd_fifo_full;
|
||||
wire cmd_fifo_full_w = ~icr | cmd_fifo_full;
|
||||
sirv_gnrl_dfflr #(1) cmd_fifo_full_r_dfflr (cmd_fifo_full_en, cmd_fifo_full_w, cmd_fifo_full_r, clk, rst_n);
|
||||
|
||||
//cmd_fifo_empty
|
||||
wire cmd_fifo_empty_r;
|
||||
wire cmd_fifo_empty_en = icr | cmd_fifo_empty;
|
||||
wire cmd_fifo_empty_w = ~icr | cmd_fifo_empty;
|
||||
sirv_gnrl_dfflr #(1) cmd_fifo_empty_r_dfflr (cmd_fifo_empty_en, cmd_fifo_empty_w, cmd_fifo_empty_r, clk, rst_n);
|
||||
|
||||
//irisr
|
||||
//Interrupt Status Register
|
||||
//[31 :6] --> Reserved
|
||||
//[5 ] --> crc_error Interrupt Status
|
||||
//[4 ] --> phase_adj_req Interrupt Status
|
||||
//[3 ] --> train_ready Interrupt Status
|
||||
//[2 ] --> link_down Interrupt Status
|
||||
//[1 ] --> cmd_fifo_empty Interrupt Status
|
||||
//[0 ] --> cmd_fifo_full Interrupt Status
|
||||
|
||||
assign irisr[5 ] = crc_error_r ;
|
||||
assign irisr[4 ] = phase_adj_req_r ;
|
||||
assign irisr[3 ] = train_ready_r ;
|
||||
assign irisr[2 ] = link_down_r ;
|
||||
assign irisr[1 ] = cmd_fifo_full_r ;
|
||||
assign irisr[0 ] = cmd_fifo_empty_r ;
|
||||
|
||||
// ------------------------------------------------------
|
||||
// -- Interrupt Status Register - Read Only
|
||||
//
|
||||
// This register contains the status of all
|
||||
// DA4008 Chip interrupts after masking.
|
||||
// ------------------------------------------------------
|
||||
sirv_gnrl_dffr #(6) isr_dffr (irisr, isr, clk, rst_n);
|
||||
|
||||
//misr
|
||||
wire[5:0] misr_w = imr & irisr;
|
||||
sirv_gnrl_dffr #(6) misr_dffr (misr_w, misr, clk, rst_n);
|
||||
|
||||
//irq
|
||||
wire irq_w = |misr;
|
||||
sirv_gnrl_dffr #(1) irq_dffr (irq_w, irq, clk, rst_n);
|
||||
|
||||
|
||||
//sync ctrl
|
||||
assign sync_oen = syncr[18 ] ;
|
||||
assign int_sync_en = syncr[17 ] ;
|
||||
assign int_sync = syncr[16 ] ;
|
||||
assign sync_delay = syncr[15:0] ;
|
||||
|
||||
//Ramp & Data Select
|
||||
//Data Select
|
||||
assign dout_sel = doselr ;
|
||||
//RAMP cfg
|
||||
assign ramp_en = doselr ;
|
||||
assign ramp_step = rampctr[23:16] ;
|
||||
assign ramp_fixed_value = rampctr[15:8] ;
|
||||
assign ramp_fixed = rampctr[0] ;
|
||||
assign ramp_ifs = rampifsr ;
|
||||
|
||||
//LVDS
|
||||
assign force_train = lvdsftr ;
|
||||
assign tap_force = lvdstfr ;
|
||||
assign tap_step = lvdstsr ;
|
||||
assign tap_adj_mask = lvdstamr;
|
||||
assign train_threshold = lvdsthr ;
|
||||
assign descram_en = lvdsdser;
|
||||
assign always_on = lvdstaor;
|
||||
|
||||
endmodule
|
||||
|
||||
`undef IDR
|
||||
`undef VIDR
|
||||
`undef DATER
|
||||
`undef VERR
|
||||
`undef TESTR
|
||||
`undef ISR
|
||||
`undef MISR
|
||||
`undef SFRTR
|
||||
`undef SFRR
|
||||
`undef RAMPCTR
|
||||
`undef RAMPIFSR
|
||||
`undef DOSELR
|
||||
`undef LVDSFTR
|
||||
`undef LVDSTFR
|
||||
`undef LVDSTSR
|
||||
`undef LVDSTHR
|
||||
`undef LVDSSR
|
||||
`undef LVDSFSCR
|
||||
`undef LVDSCECR
|
||||
`undef LVDSTAMR
|
||||
`undef LVDSDSER
|
||||
`undef LVDSTAOR
|
||||
`undef LVDSFSTR
|
||||
`undef LVDSTSTR
|
||||
`undef IMR
|
||||
`undef MISR
|
||||
|
|
@ -0,0 +1,212 @@
|
|||
|
||||
|
||||
`include "../define/chip_define.v"
|
||||
module da4008_chip_top (
|
||||
//spi port
|
||||
input PI_sclk // Spi Clock
|
||||
,input PI_csn // Spi Chip Select active low
|
||||
,input PI_mosi // Spi Mosi
|
||||
,output PO_miso // Spi Miso
|
||||
//irq
|
||||
,output PO_irq
|
||||
//system port
|
||||
,input PI_async_rstn
|
||||
,input PI_sync_in
|
||||
,output PO_sync_out
|
||||
|
||||
,input clk
|
||||
//lvds rx
|
||||
,input [3 :0] lvds_data
|
||||
,input [0 :0] lvds_valid
|
||||
,input [0 :0] lvds_clk
|
||||
,output [2 :0] phase_tap
|
||||
//DAC Data
|
||||
,output [6 :0] MSB_OUT [63:0]
|
||||
,output [4 :0] LSB_OUT [63:0]
|
||||
,output MSB_DUM [63:0]
|
||||
,output DEM_VLD
|
||||
//DAC Cfg Port
|
||||
,output [3 :0] Rterm
|
||||
,output [2 :0] CasAddr
|
||||
,output [2 :0] CasDw
|
||||
,output [9 :0] IMainCtrl
|
||||
,output [3 :0] IBleedCtrl
|
||||
,output [3 :0] ICkCml
|
||||
,output [31 :0] CurRsv0
|
||||
,output [31 :0] CurRsv1
|
||||
//CLK Cfg Port
|
||||
,output [0 :0] CcalRstn
|
||||
,output [3 :0] EnAllP
|
||||
,output [0 :0] DccEn
|
||||
,output [0 :0] CasGateCkCtrl
|
||||
,output [0 :0] SpiEnPi
|
||||
,output [0 :0] SpiEnQec
|
||||
,output [0 :0] SpiEnDcc
|
||||
,output [4 :0] SpiQecCtrlIp
|
||||
,output [4 :0] SpiQecCtrlIn
|
||||
,output [4 :0] SpiQecCtrlQp
|
||||
,output [4 :0] SpiQecCtrlQn
|
||||
,output [5 :0] SpiDccCtrlIup
|
||||
,output [5 :0] SpiDccCtrlIdn
|
||||
,output [5 :0] SpiDccCtrlQup
|
||||
,output [5 :0] SpiDccCtrlQdn
|
||||
,output [7 :0] SpiSiqNOut
|
||||
,output [7 :0] SpiSiqPOut
|
||||
,output [3 :0] SpiSiPOut
|
||||
,output [3 :0] SpiSqPOut
|
||||
,output [2 :0] CrtlCrossOverN
|
||||
,output [2 :0] CrtlCrossOverP
|
||||
,output [31 :0] CcalRsv0
|
||||
,output [31 :0] CcalRsv1
|
||||
,output [3 :0] SelCk10GDig
|
||||
,output [3 :0] SelCk2p5GDig
|
||||
,output [8 :0] SelCk625MDig
|
||||
,output [15 :0] P2sDataEn
|
||||
,output [15 :0] P2sEnAllP
|
||||
,output [15 :0] EnPiP
|
||||
,output [15 :0] CkDivRstn
|
||||
,output [31 :0] p2srsv0
|
||||
,output [31 :0] p2srsv1
|
||||
,output [15 :0] CkRxSw
|
||||
,output [15 :0] RstnCk
|
||||
,output [15 :0] CtrlZin
|
||||
);
|
||||
|
||||
//------------------------------iopad instantiation start--------------------------------------
|
||||
// iopad
|
||||
//---------------------------------------------------------------------------------------------
|
||||
wire async_rstn ;
|
||||
wire sync_in ;
|
||||
wire sync_out ;
|
||||
wire sclk ;
|
||||
wire csn ;
|
||||
wire mosi ;
|
||||
wire miso ;
|
||||
wire oen ;
|
||||
wire irq ;
|
||||
|
||||
|
||||
iopad U_iopad (
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++//
|
||||
// PAD Strat //
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++//
|
||||
.PI_async_rstn ( PI_async_rstn )
|
||||
,.PI_sync_in ( PI_sync_in )
|
||||
,.PO_sync_out ( PO_sync_out )
|
||||
,.PI_sclk ( PI_sclk )
|
||||
,.PI_csn ( PI_csn )
|
||||
,.PI_mosi ( PI_mosi )
|
||||
,.PO_miso ( PO_miso )
|
||||
,.PO_irq ( PO_irq )
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++//
|
||||
// PAD End //
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++//
|
||||
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++//
|
||||
// Internal signal Start //
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++//
|
||||
,.async_rstn ( async_rstn )
|
||||
,.sync_in ( sync_in )
|
||||
,.sync_out ( sync_out )
|
||||
,.sclk ( sclk )
|
||||
,.csn ( csn )
|
||||
,.mosi ( mosi )
|
||||
,.miso ( miso )
|
||||
,.oen ( oen )
|
||||
,.irq_n ( ~irq )
|
||||
);
|
||||
|
||||
|
||||
//------------------------------spi_slave instantiation start----------------------------------
|
||||
// spi_slave
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
wire [7 :0] wave_data_out [63:0] ;
|
||||
wire wave_data_valid ;
|
||||
wire [14 :0] Set [63:0] ;
|
||||
wire PrbsEn ;
|
||||
digital_top digital_top (
|
||||
.clk ( clk )
|
||||
,.rst_n ( async_rstn )
|
||||
,.sync_in ( sync_in )
|
||||
,.sync_out ( sync_out )
|
||||
,.cfgid ( 5'b00000 )
|
||||
,.sclk ( sclk )
|
||||
,.csn ( csn )
|
||||
,.mosi ( mosi )
|
||||
,.miso ( miso )
|
||||
,.oen ( oen )
|
||||
,.irq ( irq )
|
||||
,.wave_data_out ( wave_data_out )
|
||||
,.wave_data_valid ( wave_data_valid )
|
||||
,.lvds_data ( lvds_data )
|
||||
,.lvds_valid ( lvds_valid )
|
||||
,.lvds_clk ( lvds_clk )
|
||||
,.phase_tap ( phase_tap )
|
||||
,.Rterm ( Rterm )
|
||||
,.PrbsEn ( PrbsEn )
|
||||
,.Set ( Set )
|
||||
,.CasAddr ( CasAddr )
|
||||
,.CasDw ( CasDw )
|
||||
,.IMainCtrl ( IMainCtrl )
|
||||
,.IBleedCtrl ( IBleedCtrl )
|
||||
,.ICkCml ( ICkCml )
|
||||
,.CurRsv0 ( CurRsv0 )
|
||||
,.CurRsv1 ( CurRsv1 )
|
||||
,.CcalRstn ( CcalRstn )
|
||||
,.EnAllP ( EnAllP )
|
||||
,.DccEn ( DccEn )
|
||||
,.CasGateCkCtrl ( CasGateCkCtrl )
|
||||
,.SpiEnPi ( SpiEnPi )
|
||||
,.SpiEnQec ( SpiEnQec )
|
||||
,.SpiEnDcc ( SpiEnDcc )
|
||||
,.SpiQecCtrlIp ( SpiQecCtrlIp )
|
||||
,.SpiQecCtrlIn ( SpiQecCtrlIn )
|
||||
,.SpiQecCtrlQp ( SpiQecCtrlQp )
|
||||
,.SpiQecCtrlQn ( SpiQecCtrlQn )
|
||||
,.SpiDccCtrlIup ( SpiDccCtrlIup )
|
||||
,.SpiDccCtrlIdn ( SpiDccCtrlIdn )
|
||||
,.SpiDccCtrlQup ( SpiDccCtrlQup )
|
||||
,.SpiDccCtrlQdn ( SpiDccCtrlQdn )
|
||||
,.SpiSiqNOut ( SpiSiqNOut )
|
||||
,.SpiSiqPOut ( SpiSiqPOut )
|
||||
,.SpiSiPOut ( SpiSiPOut )
|
||||
,.SpiSqPOut ( SpiSqPOut )
|
||||
,.CrtlCrossOverN ( CrtlCrossOverN )
|
||||
,.CrtlCrossOverP ( CrtlCrossOverP )
|
||||
,.CcalRsv0 ( CcalRsv0 )
|
||||
,.CcalRsv1 ( CcalRsv1 )
|
||||
,.SelCk10GDig ( SelCk10GDig )
|
||||
,.SelCk2p5GDig ( SelCk2p5GDig )
|
||||
,.SelCk625MDig ( SelCk625MDig )
|
||||
,.P2sDataEn ( P2sDataEn )
|
||||
,.P2sEnAllP ( P2sEnAllP )
|
||||
,.EnPiP ( EnPiP )
|
||||
,.CkDivRstn ( CkDivRstn )
|
||||
,.p2srsv0 ( p2srsv0 )
|
||||
,.p2srsv1 ( p2srsv1 )
|
||||
,.CkRxSw ( CkRxSw )
|
||||
,.RstnCk ( RstnCk )
|
||||
,.CtrlZin ( CtrlZin )
|
||||
);
|
||||
|
||||
//------------------------------spi_slave instantiation start----------------------------------
|
||||
// DEM
|
||||
//---------------------------------------------------------------------------------------------
|
||||
sirv_gnrl_dffr #(1) DEM_VLD_dffr (wave_data_valid, DEM_VLD, clk, async_rstn);
|
||||
|
||||
DEM_PhaseSync_4008 U_DEM_PhaseSync_4008 (
|
||||
.clk ( clk )
|
||||
,.prbs_en ( PrbsEn )
|
||||
,.RST_N ( async_rstn )
|
||||
,.dem_set ( Set )
|
||||
,.data_in ( wave_data_out )
|
||||
,.MSB_OUT ( MSB_OUT )
|
||||
,.LSB_OUT ( LSB_OUT )
|
||||
,.MSB_DUM ( MSB_DUM )
|
||||
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
`include "../define/chip_undefine.v"
|
||||
|
|
@ -0,0 +1,529 @@
|
|||
//+FHDR--------------------------------------------------------------------------------------------------------
|
||||
// Company:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// File Name : digital_top.v
|
||||
// Department :
|
||||
// Author : pwy
|
||||
// Author's Tel :
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Relese History
|
||||
// Version Date Author Description
|
||||
// 1.2 2024-04-16 pwy XYZ control the top-level module
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Keywords :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Parameter
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Target Device:
|
||||
// Tool versions:
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Reuse Issues
|
||||
// Reset Strategy:
|
||||
// Clock Domains:
|
||||
// Critical Timing:
|
||||
// Asynchronous I/F:
|
||||
// Synthesizable (y/n):
|
||||
// Other:
|
||||
//-FHDR--------------------------------------------------------------------------------------------------------
|
||||
|
||||
`include "../define/chip_define.v"
|
||||
|
||||
module digital_top (
|
||||
//system port
|
||||
input clk // System Main Clock
|
||||
,input rst_n // Spi Reset active low
|
||||
,input sync_in
|
||||
,input sync_out
|
||||
//spi port
|
||||
,input [4 :0] cfgid
|
||||
,input sclk // Spi Clock
|
||||
,input csn // Spi Chip Select active low
|
||||
,input mosi // Spi Mosi
|
||||
,output miso // Spi Miso
|
||||
,output oen
|
||||
//irq
|
||||
,output irq
|
||||
//wave port
|
||||
,output [7 :0] wave_data_out [63:0]
|
||||
,output wave_data_valid
|
||||
//lvds rx
|
||||
,input [3 :0] lvds_data
|
||||
,input [0 :0] lvds_valid
|
||||
,input [0 :0] lvds_clk
|
||||
,output [2 :0] phase_tap
|
||||
//DAC Cfg Port
|
||||
,output [3 :0] Rterm
|
||||
,output PrbsEn
|
||||
,output [14 :0] Set [63:0]
|
||||
,output [2 :0] CasAddr
|
||||
,output [2 :0] CasDw
|
||||
,output [9 :0] IMainCtrl
|
||||
,output [3 :0] IBleedCtrl
|
||||
,output [3 :0] ICkCml
|
||||
,output [31 :0] CurRsv0
|
||||
,output [31 :0] CurRsv1
|
||||
//CLK Cfg Port
|
||||
,output [0 :0] CcalRstn
|
||||
,output [3 :0] EnAllP
|
||||
,output [0 :0] DccEn
|
||||
,output [0 :0] CasGateCkCtrl
|
||||
,output [0 :0] SpiEnPi
|
||||
,output [0 :0] SpiEnQec
|
||||
,output [0 :0] SpiEnDcc
|
||||
,output [4 :0] SpiQecCtrlIp
|
||||
,output [4 :0] SpiQecCtrlIn
|
||||
,output [4 :0] SpiQecCtrlQp
|
||||
,output [4 :0] SpiQecCtrlQn
|
||||
,output [5 :0] SpiDccCtrlIup
|
||||
,output [5 :0] SpiDccCtrlIdn
|
||||
,output [5 :0] SpiDccCtrlQup
|
||||
,output [5 :0] SpiDccCtrlQdn
|
||||
,output [7 :0] SpiSiqNOut
|
||||
,output [7 :0] SpiSiqPOut
|
||||
,output [3 :0] SpiSiPOut
|
||||
,output [3 :0] SpiSqPOut
|
||||
,output [2 :0] CrtlCrossOverN
|
||||
,output [2 :0] CrtlCrossOverP
|
||||
,output [31 :0] CcalRsv0
|
||||
,output [31 :0] CcalRsv1
|
||||
,output [3 :0] SelCk10GDig
|
||||
,output [3 :0] SelCk2p5GDig
|
||||
,output [8 :0] SelCk625MDig
|
||||
,output [15 :0] P2sDataEn
|
||||
,output [15 :0] P2sEnAllP
|
||||
,output [15 :0] EnPiP
|
||||
,output [15 :0] CkDivRstn
|
||||
,output [31 :0] p2srsv0
|
||||
,output [31 :0] p2srsv1
|
||||
,output [15 :0] CkRxSw
|
||||
,output [15 :0] RstnCk
|
||||
,output [15 :0] CtrlZin
|
||||
);
|
||||
|
||||
//------------------------------spi_slave instantiation start----------------------------------
|
||||
// spi_slave
|
||||
//---------------------------------------------------------------------------------------------
|
||||
sram_if#(25,32) mst(clk);
|
||||
sram_if#(20,32) slv[3:0](clk);
|
||||
//connect pll
|
||||
wire [31 :0] clk_wrdata ;
|
||||
wire clk_wren ;
|
||||
wire [7 :0] clk_rwaddr ;
|
||||
wire clk_rden ;
|
||||
wire [31 :0] clk_rddata ;
|
||||
//connect system
|
||||
wire [31 :0] sys_wrdata ;
|
||||
wire sys_wren ;
|
||||
wire [24 :0] sys_rwaddr ;
|
||||
wire sys_rden ;
|
||||
wire [31 :0] sys_rddata ;
|
||||
|
||||
wire pll_rstn_o;
|
||||
|
||||
assign mst.wben = 4'hf;
|
||||
|
||||
spi_slave U_spi_slave (
|
||||
.clk ( clk )
|
||||
,.rst_n ( pll_rstn_o )
|
||||
,.cfgid ( cfgid )
|
||||
,.sclk ( sclk )
|
||||
,.csn ( csn )
|
||||
,.mosi ( mosi )
|
||||
,.miso ( miso )
|
||||
,.oen ( oen )
|
||||
,.pll_wrdata ( clk_wrdata )
|
||||
,.pll_wren ( clk_wren )
|
||||
,.pll_rwaddr ( clk_rwaddr )
|
||||
,.pll_rden ( clk_rden )
|
||||
,.pll_rddata ( clk_rddata )
|
||||
,.sys_wrdata ( mst.din )
|
||||
,.sys_wren ( mst.wren )
|
||||
,.sys_rwaddr ( mst.addr )
|
||||
,.sys_rden ( mst.rden )
|
||||
,.sys_rddata ( mst.dout )
|
||||
);
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// spi_slave
|
||||
//------------------------------spi_slave instantiation end------------------------------------
|
||||
|
||||
spi_bus_decoder #(
|
||||
.SLVNUM ( `SLVNUM )
|
||||
,.SPIBUS_CMD_REG ( `SPIBUS_CMD_REG )
|
||||
,.SPIBUS_OUT_REG ( `SPIBUS_OUT_REG )
|
||||
) U_spi_bus_decoder (
|
||||
.clk ( clk )
|
||||
,.rst_n ( pll_rstn_o )
|
||||
,.mst ( mst )
|
||||
,.slv ( slv )
|
||||
);
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// spi_bus_decoder
|
||||
//------------------------------spi_bus_decoder instantiation end------------------------------
|
||||
|
||||
//-----------------------------system_regfile instantiation start------------------------------
|
||||
// system_regfile as slave device 0
|
||||
//---------------------------------------------------------------------------------------------
|
||||
wire [2 :0] awg_status ;
|
||||
wire awg_busy ;
|
||||
wire sys_soft_rstn ;
|
||||
wire dout_sel ;
|
||||
wire [15 :0] sync_delay ;
|
||||
wire int_sync ;
|
||||
wire int_sync_en ;
|
||||
wire sync_oen ;
|
||||
wire ramp_en ;
|
||||
wire [31 :0] ramp_ifs ;
|
||||
wire [7 :0] ramp_step ;
|
||||
wire ramp_fixed ;
|
||||
wire [7 :0] ramp_fixed_value ;
|
||||
//LVDS
|
||||
wire force_train ;
|
||||
wire tap_force ;
|
||||
wire [2 :0] tap_step ;
|
||||
wire [2 :0] tap_adj_mask ;
|
||||
wire [19 :0] train_threshold ;
|
||||
wire descram_en ;
|
||||
wire always_on ;
|
||||
;
|
||||
wire link_down ;
|
||||
wire train_ready ;
|
||||
wire crc_error ;
|
||||
wire phase_adj_req ;
|
||||
wire [31 :0] frame_success_cnt;
|
||||
wire [31 :0] crc_err_cnt ;
|
||||
wire prefilling ;
|
||||
wire [31 :0] train_status ;
|
||||
wire [31 :0] frame_status ;
|
||||
|
||||
systemregfile U_systemregfile (
|
||||
.clk ( clk )
|
||||
,.rst_n ( pll_rstn_o )
|
||||
,.wrdata ( slv[0].din )
|
||||
,.wren ( slv[0].wren )
|
||||
,.rwaddr ( slv[0].addr[15:0] )
|
||||
,.rden ( slv[0].rden )
|
||||
,.rddata ( slv[0].dout )
|
||||
,.irq ( irq )
|
||||
,.cmd_fifo_full ( cmd_fifo_full )
|
||||
,.cmd_fifo_empty ( cmd_fifo_empty )
|
||||
,.awg_status ( awg_status )
|
||||
,.awg_busy ( awg_busy )
|
||||
,.sys_soft_rstn ( sys_soft_rstn )
|
||||
,.dout_sel ( dout_sel )
|
||||
,.sync_delay ( sync_delay )
|
||||
,.int_sync ( int_sync )
|
||||
,.int_sync_en ( int_sync_en )
|
||||
,.sync_oen ( sync_oen )
|
||||
,.ramp_en ( ramp_en )
|
||||
,.ramp_ifs ( ramp_ifs )
|
||||
,.ramp_step ( ramp_step )
|
||||
,.ramp_fixed ( ramp_fixed )
|
||||
,.ramp_fixed_value ( ramp_fixed_value )
|
||||
,.force_train ( force_train )
|
||||
,.tap_force ( tap_force )
|
||||
,.tap_step ( tap_step )
|
||||
,.tap_adj_mask ( tap_adj_mask )
|
||||
,.train_threshold ( train_threshold )
|
||||
,.descram_en ( descram_en )
|
||||
,.always_on ( always_on )
|
||||
,.link_down ( link_down )
|
||||
,.train_ready ( train_ready )
|
||||
,.crc_error ( crc_error )
|
||||
,.phase_adj_req ( phase_adj_req )
|
||||
,.phase_tap ( phase_tap )
|
||||
,.frame_success_cnt ( frame_success_cnt )
|
||||
,.crc_err_cnt ( crc_err_cnt )
|
||||
,.prefilling ( prefilling )
|
||||
,.train_status ( train_status )
|
||||
,.frame_status ( frame_status )
|
||||
);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// system_regfile
|
||||
//------------------------------system_regfile instantiation end-------------------------------
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// rst_gen_unit instantiation start
|
||||
//---------------------------------------------------------------------------------------------
|
||||
wire ch0_rstn_o;
|
||||
|
||||
rst_gen_unit U_rst_gen_unit (
|
||||
.async_rstn_i ( rst_n )
|
||||
,.por_rstn_i ( 1'b1 )
|
||||
,.sys_soft_resetn_i ( sys_soft_rstn )
|
||||
,.ch0_soft_rstn_i ( 1'b1 )
|
||||
,.ch1_soft_rstn_i ( 1'b1 )
|
||||
,.ch2_soft_rstn_i ( 1'b1 )
|
||||
,.ch3_soft_rstn_i ( 1'b1 )
|
||||
,.clk ( clk )
|
||||
,.ch0_rstn_o ( ch0_rstn_o )
|
||||
,.ch1_rstn_o ( )
|
||||
,.ch2_rstn_o ( )
|
||||
,.ch3_rstn_o ( )
|
||||
,.pll_rstn_o ( pll_rstn_o )
|
||||
);
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// DW_stream_sync instantiation start
|
||||
//---------------------------------------------------------------------------------------------
|
||||
wire dst_valid ;
|
||||
wire [3 :0] dst_data ;
|
||||
wire prefill_d ;
|
||||
DW_stream_sync #(
|
||||
.width ( 4 )
|
||||
,.depth ( 32 )
|
||||
,.prefill_lvl ( 16 )
|
||||
,.tst_mode ( 0 )
|
||||
,.verif_en ( 0 )
|
||||
) u_dw_stream_sync (
|
||||
.clk_s ( lvds_clk )
|
||||
,.rst_s_n ( pll_rstn_o )
|
||||
,.init_s_n ( 1'b1 )
|
||||
,.clr_s ( 1'b0 )
|
||||
,.send_s ( 1'b1 )
|
||||
,.data_s ( lvds_data )
|
||||
,.clr_sync_s ( )
|
||||
,.clr_in_prog_s ( )
|
||||
,.clr_cmplt_s ( )
|
||||
,.clk_d ( clk )
|
||||
,.rst_d_n ( pll_rstn_o )
|
||||
,.init_d_n ( 1'b1 )
|
||||
,.clr_d ( 1'b0 )
|
||||
,.prefill_d ( prefill_d )
|
||||
,.clr_in_prog_d ( )
|
||||
,.clr_sync_d ( )
|
||||
,.clr_cmplt_d ( )
|
||||
,.data_avail_d ( dst_valid )
|
||||
,.data_d ( dst_data )
|
||||
,.prefilling_d ( prefilling )
|
||||
,.test ( 1'b0 )
|
||||
);
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// lvds_rx_4ch instantiation start
|
||||
//---------------------------------------------------------------------------------------------
|
||||
parameter FIFO_DEPTH = 64;
|
||||
parameter SCRAMBLER_SEED = 32'hFFFFFFFF;
|
||||
|
||||
wire [511:0] wave_awrdata ;
|
||||
wire [0 :0] wave_awren ;
|
||||
wire [12 :0] wave_arwaddr ;
|
||||
wire [63 :0] wave_awrmask ;
|
||||
|
||||
ulink_rx #(
|
||||
.FIFO_DEPTH ( FIFO_DEPTH )
|
||||
,.SCRAMBLER_SEED ( SCRAMBLER_SEED )
|
||||
) dut (
|
||||
.clk ( clk )
|
||||
,.rst_n ( pll_rstn_o )
|
||||
,.serial_in ( dst_data )
|
||||
,.patn_count ( train_threshold )
|
||||
,.tap_step ( tap_step )
|
||||
,.descram_en ( descram_en )
|
||||
,.link_down ( link_down )
|
||||
,.delay_tap ( phase_tap )
|
||||
,.wr_addr ( wave_arwaddr )
|
||||
,.wr_data ( wave_awrdata )
|
||||
,.wr_en ( wave_awren )
|
||||
,.byte_mask ( wave_awrmask )
|
||||
,.crc_error ( crc_error )
|
||||
,.tap_adj_mask ( tap_adj_mask )
|
||||
,.tap_force ( tap_force )
|
||||
,.tap_adj_req ( tap_adj_req )
|
||||
,.frame_done ( frame_done )
|
||||
,.train_status ( train_status )
|
||||
,.frame_status ( frame_status )
|
||||
,.always_on ( always_on )
|
||||
,.prefilling ( prefilling )
|
||||
,.prefill_start ( prefill_d )
|
||||
,.train_ready ( train_ready )
|
||||
,.force_train ( force_train )
|
||||
);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// sync_int
|
||||
//------------------------------sync_int instantiation start-----------------------------------
|
||||
|
||||
wire sync_int;
|
||||
wire sync_pulse;
|
||||
syncer #(1, 2) sync_in_syncer (clk, pll_rstn_o, sync_in, sync_int);
|
||||
|
||||
sirv_gnrl_dffr #(1) sync_out_dffr (sync_pulse & sync_oen, sync_out, clk, rst_n);
|
||||
assign sync_out = sync_pulse;
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// Synchronization Signal Delay Adjustment Module instantiation start
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
wire sync_src = (int_sync | sync_int) & int_sync_en;
|
||||
|
||||
pulse_generator pulse_inst_sync (
|
||||
.clk ( clk )
|
||||
,.rst_n ( pll_rstn_o )
|
||||
,.pulse_en ( sync_src )
|
||||
,.delay ( sync_delay )
|
||||
,.width ( 16'd1 )
|
||||
,.inv_en ( 1'b0 )
|
||||
,.pulse ( sync_pulse )
|
||||
);
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// sync_int
|
||||
//------------------------------sync_int instantiation end-------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// awg_top instantiation start
|
||||
//---------------------------------------------------------------------------------------------
|
||||
wire [511:0] wave_data_out_bank ;
|
||||
|
||||
wire [7 :0] awg_data_out [63:0] ;
|
||||
wire awg_data_valid ;
|
||||
|
||||
awg_top U_awg_top (
|
||||
.clk ( clk )
|
||||
,.rst_n ( ch0_rstn_o )
|
||||
,.start ( sync_pulse )
|
||||
,.wave_awrdata ( wave_awrdata )
|
||||
,.wave_awren ( wave_awren )
|
||||
,.wave_arwaddr ( wave_arwaddr )
|
||||
,.wave_awrmask ( wave_awrmask )
|
||||
,.wave_bwrdata ( slv[2].din )
|
||||
,.wave_bwren ( slv[2].wren )
|
||||
,.wave_brwaddr ( slv[2].addr[18:0] )
|
||||
,.wave_brden ( slv[2].rden )
|
||||
,.wave_brddata ( slv[2].dout )
|
||||
,.cmd_fifo_bwrdata ( slv[1].din )
|
||||
,.cmd_fifo_bwren ( slv[1].wren )
|
||||
,.cmd_fifo_brwaddr ( slv[1].addr[7 :0] )
|
||||
,.cmd_fifo_brden ( slv[1].rden )
|
||||
,.cmd_fifo_brddata ( slv[1].dout )
|
||||
,.wave_data_out ( wave_data_out_bank )
|
||||
,.wave_valid_out ( awg_data_valid )
|
||||
,.cmd_fifo_empty ( cmd_fifo_empty )
|
||||
,.cmd_fifo_full ( cmd_fifo_full )
|
||||
,.status ( awg_status )
|
||||
,.wave_busy ( awg_busy )
|
||||
);
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for(i = 0; i < 64; i++) begin
|
||||
assign awg_data_out[i] = wave_data_out_bank[8*i +: 8];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// ramp_gen instantiation start
|
||||
//---------------------------------------------------------------------------------------------
|
||||
wire [7 :0] ramp_data [63:0];
|
||||
wire ramp_vld;
|
||||
ramp_gen U_ramp_gen (
|
||||
//system port
|
||||
.clk ( clk )
|
||||
,.rst_n ( rst_n )
|
||||
,.dac_mode_sel ( 2'b10 )
|
||||
,.cen ( ramp_en )
|
||||
,.step ( ramp_step )
|
||||
,.ifs ( ramp_ifs )
|
||||
,.fixed ( ramp_fixed )
|
||||
,.fixed_value ( ramp_fixed_value )
|
||||
,.ramp ( ramp_data )
|
||||
,.ramp_vld ( ramp_vld )
|
||||
);
|
||||
|
||||
|
||||
wire [7 :0] wave_data_out_i [63:0] = dout_sel ? ramp_data : awg_data_out ;
|
||||
wire wave_data_valid_i = dout_sel ? ramp_vld : awg_data_valid ;
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// dacif instantiation start
|
||||
//---------------------------------------------------------------------------------------------
|
||||
dacif dacif_inst (
|
||||
.clk ( clk )
|
||||
,.rstn ( rst_n )
|
||||
,.din_vld ( wave_data_valid_i )
|
||||
,.din ( wave_data_out_i )
|
||||
,.dout_vld ( wave_data_valid )
|
||||
,.dout ( wave_data_out )
|
||||
);
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// dac_regfile instantiation start
|
||||
//---------------------------------------------------------------------------------------------
|
||||
dac_regfile U_dac_regfile (
|
||||
.clk ( clk )
|
||||
,.rstn ( ch0_rstn_o )
|
||||
,.wrdata ( slv[3].din )
|
||||
,.wren ( slv[3].wren )
|
||||
,.rwaddr ( slv[3].addr[15:0] )
|
||||
,.rden ( slv[3].rden )
|
||||
,.rddata ( slv[3].dout )
|
||||
,.Rterm ( Rterm )
|
||||
,.PrbsEn ( PrbsEn )
|
||||
,.Set ( Set )
|
||||
,.CasAddr ( CasAddr )
|
||||
,.CasDw ( CasDw )
|
||||
,.IMainCtrl ( IMainCtrl )
|
||||
,.IBleedCtrl ( IBleedCtrl )
|
||||
,.ICkCml ( ICkCml )
|
||||
,.CurRsv0 ( CurRsv0 )
|
||||
,.CurRsv1 ( CurRsv1 )
|
||||
);
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// clk_regfile instantiation start
|
||||
//---------------------------------------------------------------------------------------------
|
||||
clk_regfile U_clk_regfile (
|
||||
.clk ( clk )
|
||||
,.rstn ( pll_rstn_o )
|
||||
,.wrdata ( clk_wrdata )
|
||||
,.wren ( clk_wren )
|
||||
,.rwaddr ( clk_rwaddr )
|
||||
,.rden ( clk_rden )
|
||||
,.rddata ( clk_rddata )
|
||||
,.CcalRstn ( CcalRstn )
|
||||
,.EnAllP ( EnAllP )
|
||||
,.DccEn ( DccEn )
|
||||
,.CasGateCkCtrl ( CasGateCkCtrl )
|
||||
,.SpiEnPi ( SpiEnPi )
|
||||
,.SpiEnQec ( SpiEnQec )
|
||||
,.SpiEnDcc ( SpiEnDcc )
|
||||
,.SpiQecCtrlIp ( SpiQecCtrlIp )
|
||||
,.SpiQecCtrlIn ( SpiQecCtrlIn )
|
||||
,.SpiQecCtrlQp ( SpiQecCtrlQp )
|
||||
,.SpiQecCtrlQn ( SpiQecCtrlQn )
|
||||
,.SpiDccCtrlIup ( SpiDccCtrlIup )
|
||||
,.SpiDccCtrlIdn ( SpiDccCtrlIdn )
|
||||
,.SpiDccCtrlQup ( SpiDccCtrlQup )
|
||||
,.SpiDccCtrlQdn ( SpiDccCtrlQdn )
|
||||
,.SpiSiqNOut ( SpiSiqNOut )
|
||||
,.SpiSiqPOut ( SpiSiqPOut )
|
||||
,.SpiSiPOut ( SpiSiPOut )
|
||||
,.SpiSqPOut ( SpiSqPOut )
|
||||
,.CrtlCrossOverN ( CrtlCrossOverN )
|
||||
,.CrtlCrossOverP ( CrtlCrossOverP )
|
||||
,.CcalRsv0 ( CcalRsv0 )
|
||||
,.CcalRsv1 ( CcalRsv1 )
|
||||
,.SelCk10GDig ( SelCk10GDig )
|
||||
,.SelCk2p5GDig ( SelCk2p5GDig )
|
||||
,.SelCk625MDig ( SelCk625MDig )
|
||||
,.P2sDataEn ( P2sDataEn )
|
||||
,.P2sEnAllP ( P2sEnAllP )
|
||||
,.EnPiP ( EnPiP )
|
||||
,.CkDivRstn ( CkDivRstn )
|
||||
,.p2srsv0 ( p2srsv0 )
|
||||
,.p2srsv1 ( p2srsv1 )
|
||||
,.CkRxSw ( CkRxSw )
|
||||
,.RstnCk ( RstnCk )
|
||||
,.CtrlZin ( CtrlZin )
|
||||
);
|
||||
|
||||
endmodule
|
||||
`include "../define/chip_undefine.v"
|
||||
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
|
||||
WAVE ?= 0
|
||||
|
||||
SIM = RTL
|
||||
|
||||
folder = simv
|
||||
|
||||
ifeq ($(WAVE),1)
|
||||
WAVE_OPTS = -debug_access+all -debug_region+cell+encrypt -P $(NOVAS_HOME)/share/PLI/VCS/linux64/novas_new_dumper.tab $(NOVAS_HOME)/share/PLI/VCS/linux64/pli.a +define+DUMP_FSDB
|
||||
WAVE_SIM_OPTS = -fsdbDumpfile=sim.fsdb
|
||||
else
|
||||
WAVE_OPTS = -debug_access+pp
|
||||
endif
|
||||
|
||||
ifeq ($(SIM),PostPr)
|
||||
VCS = vcs -full64 -sverilog -Mupdate +lint=TFIPC-L +v2k +warn=noSDFCOM_IWSBA,noNTCDNC -notice +mindelays +tchk+edge+warn +neg_tchk -negdelay +overlap +sdfverbose -sdfretain +optconfigfile+notimingcheck.cfg -override_timescale=1ns/1ps -debug_access+all $(WAVE_OPTS) -lca -q -l compile.log -cm line+cond+fsm+tgl+branch -cm_dir ./coverage/simv.vdb |tee
|
||||
else
|
||||
VCS = vcs -full64 -j8 -sverilog +lint=TFIPC-L +v2k $(WAVE_OPTS) -lca -q -timescale=1ns/1ps +nospecify -l compile.log -cm line+cond+fsm+tgl+branch -cm_dir ./coverage/simv.vdb
|
||||
endif
|
||||
|
||||
ifeq ($(SIM),PostPr)
|
||||
post_dir = ./data_PostPr
|
||||
else
|
||||
post_dir = ./data_PostSyn
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(SIM),PostSyn)
|
||||
FileList = filelist_syn.f
|
||||
else
|
||||
ifeq ($(SIM),PostPr)
|
||||
FileList = filelist_pr.f
|
||||
else
|
||||
FileList = filelist_vlg.f
|
||||
endif
|
||||
endif
|
||||
|
||||
SIMV = ./simv sync:busywait -Xdprof=timeline $(WAVE_SIM_OPTS) -l |tee sim.log
|
||||
|
||||
all:comp run
|
||||
|
||||
comp:
|
||||
${VCS} -f $(FileList) +incdir+./../../rtl/define +incdir+./../../rtl/qubitmcu +incdir+./../../model
|
||||
|
||||
run:
|
||||
${SIMV}
|
||||
|
||||
dbg:
|
||||
verdi -sverilog -f $(FileList) -top TB -ssf *.fsdb -nologo &
|
||||
|
||||
clean:
|
||||
rm -rf DVE* simv* *log ucli.key verdiLog urgReport csrc novas.* *fsdb* *.dat *.daidir *.vdb *~
|
||||
|
||||
compare:
|
||||
./compare_files.csh ${post_dir} ./data_RTL ./compare.txt
|
||||
|
||||
regress:
|
||||
./regress.csh $(SIM)
|
||||
|
||||
rmwork:
|
||||
rm -rf ./work*
|
||||
|
||||
rmdata:
|
||||
rm -rf ./data*
|
||||
cov:
|
||||
verdi -cov -covdir coverage/merged.vdb &
|
||||
cov_d:
|
||||
dve -full64 -covdir coverage/*.vdb &
|
||||
merge:
|
||||
urg -full64 -dbname coverage/merged.vdb -flex_merge union -dir coverage/simv.vdb -parallel -maxjobs 64&
|
||||
merge_i:
|
||||
urg -full64 -flex_merge union -dir coverage/merged.vdb -dir coverage/$(folder) -dbname coverage/merged.vdb -parallel -maxjobs 64&
|
||||
|
|
@ -0,0 +1,390 @@
|
|||
`include "../../rtl/define/chip_define.v"
|
||||
|
||||
`include "../../model/SPI_DRIVER.sv"
|
||||
|
||||
`include "../../model/LVDS_DRIVER.sv"
|
||||
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module TB ();
|
||||
|
||||
//###################################
|
||||
// Generate Clocks & Reset
|
||||
//###################################
|
||||
|
||||
//Generate Clock
|
||||
localparam PERIOD = 1.536;
|
||||
logic clk ;
|
||||
//clk
|
||||
clock_tb #(
|
||||
.PERIOD ( PERIOD )
|
||||
,.PHASE ( 0 )
|
||||
)clk_inst (
|
||||
.clk_out ( clk )
|
||||
);
|
||||
|
||||
//clk_40g
|
||||
logic clk_40g;
|
||||
clock_tb #(
|
||||
.PERIOD ( 0.024)
|
||||
,.PHASE ( 0 )
|
||||
)clk_40g_inst (
|
||||
.clk_out ( clk_40g )
|
||||
);
|
||||
//Generate Reset
|
||||
logic rst_n;
|
||||
|
||||
int file_path;
|
||||
string CONFIG_FILE = "";
|
||||
string DATA_O_FILE = "";
|
||||
parameter string CASE_TEMP = "../../case_temp.txt";
|
||||
parameter string DATA_TEMP = "../../data_temp.txt";
|
||||
parameter string LVDS_FILE = "../../../../case/lvds/0305/lvds.txt";
|
||||
initial begin
|
||||
file_path = $fopen(CASE_TEMP, "r");
|
||||
if(file_path != 0) begin
|
||||
$fscanf(file_path, "%s", CONFIG_FILE);
|
||||
$display(CONFIG_FILE);
|
||||
$fclose(file_path);
|
||||
end
|
||||
file_path = $fopen(DATA_TEMP, "r");
|
||||
if(file_path != 0) begin
|
||||
$fscanf(file_path, "%s", DATA_O_FILE);
|
||||
$display(DATA_O_FILE);
|
||||
$fclose(file_path);
|
||||
end
|
||||
|
||||
$fsdbAutoSwitchDumpfile(500, "./verdplus.fsdb", 1000000);
|
||||
$fsdbDumpvars();
|
||||
$fsdbDumpMDA();
|
||||
end
|
||||
|
||||
//###################################
|
||||
// configure the dut
|
||||
//###################################
|
||||
virtual spi_if vif;
|
||||
spi_if spi_bus(.clk(clk), .rstn(rst_n));
|
||||
|
||||
virtual lvds_if lvds_vif;
|
||||
lvds_if lvds_bus(.clk(clk));
|
||||
|
||||
|
||||
|
||||
initial begin
|
||||
spi_bus.sclk = 1'b1;
|
||||
spi_bus.mosi = 1'b0;
|
||||
spi_bus.csn = 1'b1;
|
||||
vif = spi_bus;
|
||||
lvds_vif = lvds_bus;
|
||||
end
|
||||
|
||||
spi_driver my_drv;
|
||||
lvds_driver lvds_drv;
|
||||
logic start;
|
||||
|
||||
initial begin
|
||||
rst_n = 1'b0;
|
||||
start = 1'b0;
|
||||
|
||||
lvds_drv = new();
|
||||
//lvds_drv.file_path = LVDS_FILE;
|
||||
lvds_drv.drv_if = lvds_vif;
|
||||
|
||||
|
||||
my_drv = new();
|
||||
my_drv.file_path = CONFIG_FILE;
|
||||
my_drv.itf = vif;
|
||||
|
||||
# 20;
|
||||
rst_n = 1'b1;
|
||||
|
||||
//lvds_drv.do_drive();
|
||||
lvds_drv.train_count = 100; // ÉèÖÃѵÁ·´ÎÊý
|
||||
lvds_drv.send_training(); // ·¢ËÍѵÁ·ÐòÁÐ
|
||||
lvds_drv.scrambler_en = 1;
|
||||
lvds_drv.send_frame_from_file(LVDS_FILE); // ·¢ËÍÊý¾ÝÖ¡
|
||||
|
||||
file_path = $fopen(DATA_O_FILE, "w");
|
||||
my_drv.do_drive(file_path);
|
||||
$fclose(file_path);
|
||||
|
||||
# 30;
|
||||
start = 1'b1;
|
||||
# PERIOD;
|
||||
# PERIOD;
|
||||
start = 1'b0;
|
||||
|
||||
# 30000;
|
||||
|
||||
file_path = $fopen(DATA_O_FILE, "w");
|
||||
my_drv.do_drive(file_path);
|
||||
$fclose(file_path);
|
||||
|
||||
start = 1'b1;
|
||||
# PERIOD;
|
||||
# PERIOD;
|
||||
start = 1'b0;
|
||||
|
||||
# 30000;
|
||||
|
||||
file_path = $fopen(DATA_O_FILE, "w");
|
||||
my_drv.do_drive(file_path);
|
||||
$fclose(file_path);
|
||||
|
||||
start = 1'b1;
|
||||
# PERIOD;
|
||||
# PERIOD;
|
||||
start = 1'b0;
|
||||
|
||||
# 30000;
|
||||
|
||||
$finish(0);
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//DUT
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//sync_out
|
||||
logic sync_out ;
|
||||
//irq
|
||||
logic irq ;
|
||||
//lvds rx
|
||||
logic [3 :0] lvds_data = '0;
|
||||
logic [0 :0] lvds_valid = '0;
|
||||
logic [0 :0] lvds_clk = '0;
|
||||
//DAC Data
|
||||
logic [6 :0] MSB_OUT [63:0] ;
|
||||
logic [4 :0] LSB_OUT [63:0] ;
|
||||
logic MSB_DUM [63:0] ;
|
||||
logic DEM_VLD ;
|
||||
//DAC Cfg Port
|
||||
logic [3 :0] Rterm ;
|
||||
logic [2 :0] CasAddr ;
|
||||
logic [2 :0] CasDw ;
|
||||
logic [9 :0] IMainCtrl ;
|
||||
logic [3 :0] IBleedCtrl ;
|
||||
logic [3 :0] ICkCml ;
|
||||
logic [31 :0] CurRsv0 ;
|
||||
logic [31 :0] CurRsv1 ;
|
||||
//CLK Cfg Port
|
||||
logic [0 :0] CcalRstn ;
|
||||
logic [3 :0] EnAllP ;
|
||||
logic [0 :0] DccEn ;
|
||||
logic [0 :0] CasGateCkCtrl ;
|
||||
logic [0 :0] SpiEnPi ;
|
||||
logic [0 :0] SpiEnQec ;
|
||||
logic [0 :0] SpiEnDcc ;
|
||||
logic [4 :0] SpiQecCtrlIp ;
|
||||
logic [4 :0] SpiQecCtrlIn ;
|
||||
logic [4 :0] SpiQecCtrlQp ;
|
||||
logic [4 :0] SpiQecCtrlQn ;
|
||||
logic [5 :0] SpiDccCtrlIup ;
|
||||
logic [5 :0] SpiDccCtrlIdn ;
|
||||
logic [5 :0] SpiDccCtrlQup ;
|
||||
logic [5 :0] SpiDccCtrlQdn ;
|
||||
logic [7 :0] SpiSiqNOut ;
|
||||
logic [7 :0] SpiSiqPOut ;
|
||||
logic [3 :0] SpiSiPOut ;
|
||||
logic [3 :0] SpiSqPOut ;
|
||||
logic [2 :0] CrtlCrossOverN ;
|
||||
logic [2 :0] CrtlCrossOverP ;
|
||||
logic [31 :0] CcalRsv0 ;
|
||||
logic [31 :0] CcalRsv1 ;
|
||||
logic [3 :0] SelCk10GDig ;
|
||||
logic [3 :0] SelCk2p5GDig ;
|
||||
logic [8 :0] SelCk625MDig ;
|
||||
logic [15 :0] P2sDataEn ;
|
||||
logic [15 :0] P2sEnAllP ;
|
||||
logic [15 :0] EnPiP ;
|
||||
logic [15 :0] CkDivRstn ;
|
||||
logic [31 :0] p2srsv0 ;
|
||||
logic [31 :0] p2srsv1 ;
|
||||
logic [15 :0] CkRxSw ;
|
||||
logic [15 :0] RstnCk ;
|
||||
logic [15 :0] CtrlZin ;
|
||||
|
||||
|
||||
da4008_chip_top U_da4008_chip_top (
|
||||
.PI_sclk ( spi_bus.sclk )
|
||||
,.PI_csn ( spi_bus.csn )
|
||||
,.PI_mosi ( spi_bus.mosi )
|
||||
,.PO_miso ( spi_bus.miso )
|
||||
,.PO_irq ( irq )
|
||||
,.PI_async_rstn ( rst_n )
|
||||
,.PI_sync_in ( start )
|
||||
,.PO_sync_out ( sync_out )
|
||||
,.clk ( clk )
|
||||
,.lvds_data ( lvds_bus.data )
|
||||
,.lvds_valid ( lvds_bus.valid )
|
||||
,.lvds_clk ( lvds_bus.clk )
|
||||
,.MSB_OUT ( MSB_OUT )
|
||||
,.LSB_OUT ( LSB_OUT )
|
||||
,.MSB_DUM ( MSB_DUM )
|
||||
,.DEM_VLD ( DEM_VLD )
|
||||
,.Rterm ( Rterm )
|
||||
,.CasAddr ( CasAddr )
|
||||
,.CasDw ( CasDw )
|
||||
,.IMainCtrl ( IMainCtrl )
|
||||
,.IBleedCtrl ( IBleedCtrl )
|
||||
,.ICkCml ( ICkCml )
|
||||
,.CurRsv0 ( CurRsv0 )
|
||||
,.CurRsv1 ( CurRsv1 )
|
||||
,.CcalRstn ( CcalRstn )
|
||||
,.EnAllP ( EnAllP )
|
||||
,.DccEn ( DccEn )
|
||||
,.CasGateCkCtrl ( CasGateCkCtrl )
|
||||
,.SpiEnPi ( SpiEnPi )
|
||||
,.SpiEnQec ( SpiEnQec )
|
||||
,.SpiEnDcc ( SpiEnDcc )
|
||||
,.SpiQecCtrlIp ( SpiQecCtrlIp )
|
||||
,.SpiQecCtrlIn ( SpiQecCtrlIn )
|
||||
,.SpiQecCtrlQp ( SpiQecCtrlQp )
|
||||
,.SpiQecCtrlQn ( SpiQecCtrlQn )
|
||||
,.SpiDccCtrlIup ( SpiDccCtrlIup )
|
||||
,.SpiDccCtrlIdn ( SpiDccCtrlIdn )
|
||||
,.SpiDccCtrlQup ( SpiDccCtrlQup )
|
||||
,.SpiDccCtrlQdn ( SpiDccCtrlQdn )
|
||||
,.SpiSiqNOut ( SpiSiqNOut )
|
||||
,.SpiSiqPOut ( SpiSiqPOut )
|
||||
,.SpiSiPOut ( SpiSiPOut )
|
||||
,.SpiSqPOut ( SpiSqPOut )
|
||||
,.CrtlCrossOverN ( CrtlCrossOverN )
|
||||
,.CrtlCrossOverP ( CrtlCrossOverP )
|
||||
,.CcalRsv0 ( CcalRsv0 )
|
||||
,.CcalRsv1 ( CcalRsv1 )
|
||||
,.SelCk10GDig ( SelCk10GDig )
|
||||
,.SelCk2p5GDig ( SelCk2p5GDig )
|
||||
,.SelCk625MDig ( SelCk625MDig )
|
||||
,.P2sDataEn ( P2sDataEn )
|
||||
,.P2sEnAllP ( P2sEnAllP )
|
||||
,.EnPiP ( EnPiP )
|
||||
,.CkDivRstn ( CkDivRstn )
|
||||
,.p2srsv0 ( p2srsv0 )
|
||||
,.p2srsv1 ( p2srsv1 )
|
||||
,.CkRxSw ( CkRxSw )
|
||||
,.RstnCk ( RstnCk )
|
||||
,.CtrlZin ( CtrlZin )
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//DEM_Reverse_64CH
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
logic vld_out ;
|
||||
logic [7 :0] data_out [63:0] ;
|
||||
|
||||
DEM_Reverse_64CH U_DEM_Reverse_64CH (
|
||||
.clk ( clk )
|
||||
,.msb_in ( MSB_OUT )
|
||||
,.lsb_in ( LSB_OUT )
|
||||
,.vld_in ( DEM_VLD )
|
||||
,.vld_out ( vld_out )
|
||||
,.data_out ( data_out )
|
||||
);
|
||||
|
||||
logic [7 :0] data_out_r [63:0] ;
|
||||
logic vld_out_r ;
|
||||
|
||||
always @(posedge clk_40g) begin
|
||||
data_out_r <= data_out ;
|
||||
vld_out_r <= vld_out ;
|
||||
end
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//DA4008 DEM output data save
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
wire add_cnt = vld_out_r;
|
||||
wire end_cnt = 1'b0;
|
||||
|
||||
logic [5 :0] cnt_c;
|
||||
wire [5 :0] cnt_n = end_cnt ? 6'h0 :
|
||||
add_cnt ? cnt_c + 1'b1 :
|
||||
cnt_c ;
|
||||
|
||||
always @(posedge clk_40g or negedge rst_n) begin
|
||||
if(rst_n==1'b0) begin
|
||||
cnt_c <= 6'd0;
|
||||
end
|
||||
else begin
|
||||
cnt_c <= cnt_n;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
logic [7:0] cs_wave;
|
||||
always @(posedge clk_40g or negedge rst_n) begin
|
||||
if(rst_n==1'b0) begin
|
||||
cs_wave <= 16'h0;
|
||||
end
|
||||
else begin
|
||||
case(cnt_c)
|
||||
6'd0 : cs_wave <= {~data_out_r[0 ][7],data_out_r[0 ][6:0]};
|
||||
6'd1 : cs_wave <= {~data_out_r[1 ][7],data_out_r[1 ][6:0]};
|
||||
6'd2 : cs_wave <= {~data_out_r[2 ][7],data_out_r[2 ][6:0]};
|
||||
6'd3 : cs_wave <= {~data_out_r[3 ][7],data_out_r[3 ][6:0]};
|
||||
6'd4 : cs_wave <= {~data_out_r[4 ][7],data_out_r[4 ][6:0]};
|
||||
6'd5 : cs_wave <= {~data_out_r[5 ][7],data_out_r[5 ][6:0]};
|
||||
6'd6 : cs_wave <= {~data_out_r[6 ][7],data_out_r[6 ][6:0]};
|
||||
6'd7 : cs_wave <= {~data_out_r[7 ][7],data_out_r[7 ][6:0]};
|
||||
6'd8 : cs_wave <= {~data_out_r[8 ][7],data_out_r[8 ][6:0]};
|
||||
6'd9 : cs_wave <= {~data_out_r[9 ][7],data_out_r[9 ][6:0]};
|
||||
6'd10 : cs_wave <= {~data_out_r[10][7],data_out_r[10][6:0]};
|
||||
6'd11 : cs_wave <= {~data_out_r[11][7],data_out_r[11][6:0]};
|
||||
6'd12 : cs_wave <= {~data_out_r[12][7],data_out_r[12][6:0]};
|
||||
6'd13 : cs_wave <= {~data_out_r[13][7],data_out_r[13][6:0]};
|
||||
6'd14 : cs_wave <= {~data_out_r[14][7],data_out_r[14][6:0]};
|
||||
6'd15 : cs_wave <= {~data_out_r[15][7],data_out_r[15][6:0]};
|
||||
6'd16 : cs_wave <= {~data_out_r[16][7],data_out_r[16][6:0]};
|
||||
6'd17 : cs_wave <= {~data_out_r[17][7],data_out_r[17][6:0]};
|
||||
6'd18 : cs_wave <= {~data_out_r[18][7],data_out_r[18][6:0]};
|
||||
6'd19 : cs_wave <= {~data_out_r[19][7],data_out_r[19][6:0]};
|
||||
6'd20 : cs_wave <= {~data_out_r[20][7],data_out_r[20][6:0]};
|
||||
6'd21 : cs_wave <= {~data_out_r[21][7],data_out_r[21][6:0]};
|
||||
6'd22 : cs_wave <= {~data_out_r[22][7],data_out_r[22][6:0]};
|
||||
6'd23 : cs_wave <= {~data_out_r[23][7],data_out_r[23][6:0]};
|
||||
6'd24 : cs_wave <= {~data_out_r[24][7],data_out_r[24][6:0]};
|
||||
6'd25 : cs_wave <= {~data_out_r[25][7],data_out_r[25][6:0]};
|
||||
6'd26 : cs_wave <= {~data_out_r[26][7],data_out_r[26][6:0]};
|
||||
6'd27 : cs_wave <= {~data_out_r[27][7],data_out_r[27][6:0]};
|
||||
6'd28 : cs_wave <= {~data_out_r[28][7],data_out_r[28][6:0]};
|
||||
6'd29 : cs_wave <= {~data_out_r[29][7],data_out_r[29][6:0]};
|
||||
6'd30 : cs_wave <= {~data_out_r[30][7],data_out_r[30][6:0]};
|
||||
6'd31 : cs_wave <= {~data_out_r[31][7],data_out_r[31][6:0]};
|
||||
6'd32 : cs_wave <= {~data_out_r[32][7],data_out_r[32][6:0]};
|
||||
6'd33 : cs_wave <= {~data_out_r[33][7],data_out_r[33][6:0]};
|
||||
6'd34 : cs_wave <= {~data_out_r[34][7],data_out_r[34][6:0]};
|
||||
6'd35 : cs_wave <= {~data_out_r[35][7],data_out_r[35][6:0]};
|
||||
6'd36 : cs_wave <= {~data_out_r[36][7],data_out_r[36][6:0]};
|
||||
6'd37 : cs_wave <= {~data_out_r[37][7],data_out_r[37][6:0]};
|
||||
6'd38 : cs_wave <= {~data_out_r[38][7],data_out_r[38][6:0]};
|
||||
6'd39 : cs_wave <= {~data_out_r[39][7],data_out_r[39][6:0]};
|
||||
6'd40 : cs_wave <= {~data_out_r[40][7],data_out_r[40][6:0]};
|
||||
6'd41 : cs_wave <= {~data_out_r[41][7],data_out_r[41][6:0]};
|
||||
6'd42 : cs_wave <= {~data_out_r[42][7],data_out_r[42][6:0]};
|
||||
6'd43 : cs_wave <= {~data_out_r[43][7],data_out_r[43][6:0]};
|
||||
6'd44 : cs_wave <= {~data_out_r[44][7],data_out_r[44][6:0]};
|
||||
6'd45 : cs_wave <= {~data_out_r[45][7],data_out_r[45][6:0]};
|
||||
6'd46 : cs_wave <= {~data_out_r[46][7],data_out_r[46][6:0]};
|
||||
6'd47 : cs_wave <= {~data_out_r[47][7],data_out_r[47][6:0]};
|
||||
6'd48 : cs_wave <= {~data_out_r[48][7],data_out_r[48][6:0]};
|
||||
6'd49 : cs_wave <= {~data_out_r[49][7],data_out_r[49][6:0]};
|
||||
6'd50 : cs_wave <= {~data_out_r[50][7],data_out_r[50][6:0]};
|
||||
6'd51 : cs_wave <= {~data_out_r[51][7],data_out_r[51][6:0]};
|
||||
6'd52 : cs_wave <= {~data_out_r[52][7],data_out_r[52][6:0]};
|
||||
6'd53 : cs_wave <= {~data_out_r[53][7],data_out_r[53][6:0]};
|
||||
6'd54 : cs_wave <= {~data_out_r[54][7],data_out_r[54][6:0]};
|
||||
6'd55 : cs_wave <= {~data_out_r[55][7],data_out_r[55][6:0]};
|
||||
6'd56 : cs_wave <= {~data_out_r[56][7],data_out_r[56][6:0]};
|
||||
6'd57 : cs_wave <= {~data_out_r[57][7],data_out_r[57][6:0]};
|
||||
6'd58 : cs_wave <= {~data_out_r[58][7],data_out_r[58][6:0]};
|
||||
6'd59 : cs_wave <= {~data_out_r[59][7],data_out_r[59][6:0]};
|
||||
6'd60 : cs_wave <= {~data_out_r[60][7],data_out_r[60][6:0]};
|
||||
6'd61 : cs_wave <= {~data_out_r[61][7],data_out_r[61][6:0]};
|
||||
6'd62 : cs_wave <= {~data_out_r[62][7],data_out_r[62][6:0]};
|
||||
6'd63 : cs_wave <= {~data_out_r[63][7],data_out_r[63][6:0]};
|
||||
endcase
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
# 测试平台说明文档 (TB.sv)
|
||||
|
||||
## 1. 概述
|
||||
|
||||
本测试平台用于验证 `da4008_chip_top` 芯片的数字功能。通过 SPI 接口配置芯片内部寄存器,并通过 LVDS 接口输入数据帧,观察芯片输出的并行数据(MSB_OUT/LSB_OUT)以及经过后处理的波形数据。测试平台包含时钟生成、复位控制、驱动器模型、待测芯片实例化以及数据采集逻辑。
|
||||
|
||||
## 2. 主要模块及功能
|
||||
|
||||
### 2.1 时钟生成
|
||||
|
||||
- **clk**:周期 1.536 ns,用于芯片主时钟。
|
||||
- **clk_40g**:周期 0.024 ns,用于高速数据采集(后处理模块采样时钟)。
|
||||
|
||||
两个时钟均由 `clock_tb` 模块实例化产生。
|
||||
|
||||
### 2.2 复位信号
|
||||
|
||||
- `rst_n`:低有效复位,初始为 0,延迟 20 ns 后置为 1。
|
||||
|
||||
### 2.3 配置文件读取
|
||||
|
||||
测试平台通过读取临时文件获取配置和数据的路径:
|
||||
|
||||
- `CASE_TEMP = "../../case_temp.txt"`:存储 SPI 配置文件路径。
|
||||
- `DATA_TEMP = "../../data_temp.txt"`:存储输出数据文件路径。
|
||||
- `LVDS_FILE = "../../../../case/lvds/0305/lvds.txt"`:LVDS 输入数据文件路径。
|
||||
|
||||
在 `initial` 块中读取这些路径,并存入 `CONFIG_FILE` 和 `DATA_O_FILE` 字符串变量。
|
||||
|
||||
### 2.4 接口及驱动器
|
||||
|
||||
- **SPI 接口**:`spi_if` 模块实例化为 `spi_bus`,包含 `sclk`、`mosi`、`miso`、`csn` 信号。通过 `virtual spi_if vif` 传递。
|
||||
- **LVDS 接口**:`lvds_if` 模块实例化为 `lvds_bus`,包含 `data`、`valid`、`clk` 信号。通过 `virtual lvds_if lvds_vif` 传递。
|
||||
- **SPI 驱动器**:`spi_driver` 类对象 `my_drv`,负责从 `CONFIG_FILE` 读取配置序列并驱动 SPI 总线,同时将读取的结果写入 `DATA_O_FILE`。
|
||||
- **LVDS 驱动器**:`lvds_driver` 类对象 `lvds_drv`,负责从 `LVDS_FILE` 读取数据帧并驱动 LVDS 总线。先发送训练序列(`train_count = 100`),然后发送加扰数据帧。
|
||||
|
||||
### 2.5 测试流程
|
||||
|
||||
1. 初始化复位和驱动器对象。
|
||||
2. 释放复位后,LVDS 驱动器发送训练序列和数据帧。
|
||||
3. 首次调用 `my_drv.do_drive(file_path)` 将 SPI 配置写入芯片(同时可能回读并保存)。
|
||||
4. 拉高 `start` 信号两个周期,启动芯片内部同步。
|
||||
5. 等待 30,000 ns 后再次调用 `do_drive` 保存数据。
|
||||
6. 重复步骤 4-5 两次,共三次数据采集。
|
||||
7. 仿真结束(`$finish`)。
|
||||
|
||||
### 2.6 待测芯片实例化
|
||||
|
||||
`da4008_chip_top` 例化为 `U_da4008_chip_top`,连接信号包括:
|
||||
|
||||
- SPI 接口:`PI_sclk`, `PI_csn`, `PI_mosi`, `PO_miso`
|
||||
- 中断:`PO_irq`
|
||||
- 同步信号:`PI_sync_in` (start), `PO_sync_out`
|
||||
- 时钟:`clk`
|
||||
- LVDS 输入:`lvds_data`, `lvds_valid`, `lvds_clk`
|
||||
- DAC 输出总线:`MSB_OUT[63:0]`, `LSB_OUT[63:0]`, `MSB_DUM[63:0]`, `DEM_VLD`
|
||||
- 各类配置端口(电流、时钟、P2S 等)
|
||||
|
||||
### 2.7 后处理模块
|
||||
|
||||
- **DEM_Reverse_64CH**:将 `MSB_OUT` 和 `LSB_OUT` 合并并反向排列,输出 64 路 8 位数据 `data_out[63:0]` 及有效信号 `vld_out`。
|
||||
- 使用 `clk_40g` 将 `data_out` 和 `vld_out` 打一拍得到 `data_out_r` 和 `vld_out_r`。
|
||||
- 计数器 `cnt_c`:在 `vld_out_r` 有效时递增(0~63 循环),用于轮询选择当前通道数据。
|
||||
- `cs_wave`:根据 `cnt_c` 选择对应通道的 `data_out_r`,并将最高位取反(可能是为了满足特定输出格式),输出 8 位波形数据。
|
||||
|
||||
### 2.8 波形记录
|
||||
|
||||
使用 `$fsdbAutoSwitchDumpfile` 和 `$fsdbDumpvars` 记录 FSDB 格式波形,支持 MDA 转储,便于调试。
|
||||
|
||||
## 3. 文件依赖
|
||||
|
||||
- `../../rtl/define/chip_define.v`:芯片定义文件。
|
||||
- `../../model/SPI_DRIVER.sv`:SPI 驱动器模型。
|
||||
- `../../model/LVDS_DRIVER.sv`:LVDS 驱动器模型。
|
||||
- `clock_tb` 时钟发生模块。
|
||||
- `spi_if`、`lvds_if` SPI接口文件。
|
||||
- `DEM_Reverse_64CH` DEM解码模块。
|
||||
|
||||
## 4. 仿真控制
|
||||
|
||||
通过修改 `case_temp.txt` 和 `data_temp.txt` 可指定不同的配置文件和输出文件。LVDS 数据文件路径固定为 `LVDS_FILE`,可根据需要修改。
|
||||
|
||||
## 5. 注意事项
|
||||
|
||||
- 仿真时间单位/精度为 1ns/1ps。
|
||||
- 驱动器的具体实现未在此文件中给出,需确保相关模型正确。
|
||||
- 多次调用 `my_drv.do_drive` 可能用于在不同时刻捕获芯片内部状态。
|
||||
- `cs_wave` 的生成方式暗示了数据采集的时序要求,需保证 `clk_40g` 与芯片输出时钟的同步关系。
|
||||
|
||||
---
|
||||
|
||||
以上为该测试平台的结构与功能说明,可作为仿真环境的使用参考。
|
||||
Binary file not shown.
|
|
@ -0,0 +1,72 @@
|
|||
|
||||
WAVE ?= 0
|
||||
|
||||
SIM = RTL
|
||||
|
||||
folder = simv
|
||||
|
||||
ifeq ($(WAVE),1)
|
||||
WAVE_OPTS = -debug_access+all -debug_region+cell+encrypt -P $(NOVAS_HOME)/share/PLI/VCS/linux64/novas_new_dumper.tab $(NOVAS_HOME)/share/PLI/VCS/linux64/pli.a +define+DUMP_FSDB
|
||||
WAVE_SIM_OPTS = -fsdbDumpfile=sim.fsdb
|
||||
else
|
||||
WAVE_OPTS = -debug_access+pp
|
||||
endif
|
||||
|
||||
ifeq ($(SIM),PostPr)
|
||||
VCS = vcs -full64 -sverilog -Mupdate +lint=TFIPC-L +v2k +warn=noSDFCOM_IWSBA,noNTCDNC -notice +mindelays +tchk+edge+warn +neg_tchk -negdelay +overlap +sdfverbose -sdfretain +optconfigfile+notimingcheck.cfg -override_timescale=1ns/1ps -debug_access+all $(WAVE_OPTS) -lca -q -l compile.log -cm line+cond+fsm+tgl+branch -cm_dir ./coverage/simv.vdb |tee
|
||||
else
|
||||
VCS = vcs -full64 -j8 -sverilog +lint=TFIPC-L +v2k $(WAVE_OPTS) -lca -q -timescale=1ns/1ps +nospecify -l compile.log -cm line+cond+fsm+tgl+branch -cm_dir ./coverage/simv.vdb
|
||||
endif
|
||||
|
||||
ifeq ($(SIM),PostPr)
|
||||
post_dir = ./data_PostPr
|
||||
else
|
||||
post_dir = ./data_PostSyn
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(SIM),PostSyn)
|
||||
FileList = filelist_syn.f
|
||||
else
|
||||
ifeq ($(SIM),PostPr)
|
||||
FileList = filelist_pr.f
|
||||
else
|
||||
FileList = filelist_vlg.f
|
||||
endif
|
||||
endif
|
||||
|
||||
SIMV = ./simv sync:busywait -Xdprof=timeline $(WAVE_SIM_OPTS) -l |tee sim.log
|
||||
|
||||
all:comp run
|
||||
|
||||
comp:
|
||||
${VCS} -f $(FileList) +incdir+./../../rtl/define +incdir+./../../rtl/qubitmcu +incdir+./../../model
|
||||
|
||||
run:
|
||||
${SIMV}
|
||||
|
||||
dbg:
|
||||
verdi -sverilog -f $(FileList) -top TB -ssf *.fsdb -nologo &
|
||||
|
||||
clean:
|
||||
rm -rf DVE* simv* *log ucli.key verdiLog urgReport csrc novas.* *fsdb* *.dat *.daidir *.vdb *~
|
||||
|
||||
compare:
|
||||
./compare_files.csh ${post_dir} ./data_RTL ./compare.txt
|
||||
|
||||
regress:
|
||||
./regress.csh $(SIM)
|
||||
|
||||
rmwork:
|
||||
rm -rf ./work*
|
||||
|
||||
rmdata:
|
||||
rm -rf ./data*
|
||||
cov:
|
||||
verdi -cov -covdir coverage/merged.vdb &
|
||||
cov_d:
|
||||
dve -full64 -covdir coverage/*.vdb &
|
||||
merge:
|
||||
urg -full64 -dbname coverage/merged.vdb -flex_merge union -dir coverage/simv.vdb -parallel -maxjobs 64&
|
||||
merge_i:
|
||||
urg -full64 -flex_merge union -dir coverage/merged.vdb -dir coverage/$(folder) -dbname coverage/merged.vdb -parallel -maxjobs 64&
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
../../../../rtl/define/chip_define.v
|
||||
../../../../sim/chip_top/TB.sv
|
||||
../../../../model/spi_if.sv
|
||||
../../../../model/DW01_addsub.v
|
||||
../../../../model/DW02_mult.v
|
||||
../../../../model/DW_mult_pipe.v
|
||||
../../../../model/clk_gen.v
|
||||
../../../../model/clock_tb.v
|
||||
../../../../model/reset_tb.v
|
||||
../../../../model/thermo2binary_top.v
|
||||
../../../../model/thermo7_binary3.v
|
||||
../../../../model/thermo15_binary4.v
|
||||
../../../../model/glbl.v
|
||||
../../../../rtl/memory/tsdn28hpcpuhdb128x128m4mw_170a_ffg0p99v0c.v
|
||||
../../../../rtl/memory/tsdn28hpcpuhdb4096x32m4mw_170a_ffg0p99v0c.v
|
||||
../../../../rtl/memory/tsdn28hpcpuhdb64x32m4mw_170a_ffg0p99v0c.v
|
||||
../../../../rtl/memory/tsdn28hpcpuhdb512x128m4mwr_170a_ffg0p99v0c.v
|
||||
../../../../rtl/memory/tsdn28hpcpuhdb4096x128m4mw_170a_ffg0p99v0c.v
|
||||
../../../../rtl/dem/DEM_31MSB_decoder_1ch.v
|
||||
../../../../rtl/dem/DEM_31MSB_decoder_16ch_XY.v
|
||||
/data/pdk/TSMCHOME/digital/Front_End/verilog/tphn28hpcpgv18_110a/tphn28hpcpgv18.v
|
||||
../../../../lib/tcbn28hpcplusbwp7t35p140.v
|
||||
../../../../syn/current/outputs/xyz_chip_top.syn.v
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
../../../../rtl/define/chip_define.v
|
||||
../../../../lib/tphn28hpcpgv18.v
|
||||
../../../../lib/tsdn28hpcpuhdb4096x128m4mw_170a_ffg0p99v0c.v
|
||||
../../../../rtl/io/iopad.v
|
||||
../../../../rtl/systemregfile/systemregfile.v
|
||||
../../../../rtl/dacif/dacif.v
|
||||
../../../../rtl/fifo/syn_fwft_fifo.v
|
||||
../../../../rtl/dac_regfile/dac_regfile.v
|
||||
../../../../rtl/lvds/ulink_rx.sv
|
||||
../../../../rtl/rstgen/rst_gen_unit.v
|
||||
../../../../rtl/rstgen/rst_sync.v
|
||||
../../../../rtl/comm/sirv_gnrl_xchecker.v
|
||||
../../../../rtl/comm/pulse_generator.sv
|
||||
../../../../rtl/comm/sirv_gnrl_dffs.v
|
||||
../../../../rtl/comm/syncer.v
|
||||
../../../../rtl/comm/ramp_gen.v
|
||||
../../../../rtl/memory/tsmc_dpram.v
|
||||
../../../../rtl/memory/sram_if.sv
|
||||
../../../../rtl/memory/sram_dmux.sv
|
||||
../../../../rtl/memory/dpram.v
|
||||
../../../../rtl/memory/bhv_spram.v
|
||||
../../../../rtl/memory/spram.v
|
||||
../../../../rtl/clk/clk_regfile.v
|
||||
../../../../rtl/awg/awg_top.sv
|
||||
../../../../rtl/awg/awg_ctrl.v
|
||||
../../../../rtl/dem/DEM_PhaseSync_4008.sv
|
||||
../../../../rtl/dem/DA4008_DEM_Parallel_PRBS_1CH.v
|
||||
../../../../rtl/dem/DA4008_DEM_Parallel_PRBS_64CH.v
|
||||
../../../../rtl/top/da4008_chip_top.sv
|
||||
../../../../rtl/top/digital_top.sv
|
||||
../../../../rtl/spi/spi_bus_decoder.sv
|
||||
../../../../rtl/spi/spi_slave.v
|
||||
../../../../rtl/spi/spi_pll.v
|
||||
../../../../rtl/spi/spi_sys.v
|
||||
../../../../model/clock_tb.v
|
||||
../../../../model/spi_if.sv
|
||||
../../../../model/clk_gen.v
|
||||
../../../../model/DEM_Reverse_64CH.v
|
||||
../../../../model/DEM_Reverse.v
|
||||
../../../../model/reset_tb.v
|
||||
../../../../model/DW_stream_sync.v
|
||||
../../../../model/DW_reset_sync.v
|
||||
../../../../model/DW_sync.v
|
||||
../../../../model/DW_pulse_sync.v
|
||||
../../../../sim/chip_top/TB.sv
|
||||
../../../../rtl/define/chip_undefine.v
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
../../rtl/define/chip_define.v
|
||||
../../sim/chip_top/TB.sv
|
||||
../../model/spi_if.sv
|
||||
../../model/DW01_addsub.v
|
||||
../../model/DW02_mult.v
|
||||
../../model/DW_mult_pipe.v
|
||||
../../model/clk_gen.v
|
||||
../../model/clock_tb.v
|
||||
../../model/reset_tb.v
|
||||
../../model/thermo2binary_top.v
|
||||
../../model/thermo7_binary3.v
|
||||
../../model/thermo15_binary4.v
|
||||
../../model/glbl.v
|
||||
../../rtl/memory/tsdn28hpcpuhdb128x128m4mw_170a_ffg0p99v0c.v
|
||||
../../rtl/memory/tsdn28hpcpuhdb4096x32m4mw_170a_ffg0p99v0c.v
|
||||
../../rtl/memory/tsdn28hpcpuhdb64x32m4mw_170a_ffg0p99v0c.v
|
||||
../../rtl/memory/tsdn28hpcpuhdb512x128m4mwr_170a_ffg0p99v0c.v
|
||||
../../rtl/memory/tsdn28hpcpuhdb4096x128m4mw_170a_ffg0p99v0c.v
|
||||
../../rtl/dem/DEM_31MSB_decoder_1ch.v
|
||||
../../rtl/dem/DEM_31MSB_decoder_16ch_XY.v
|
||||
/data/pdk/TSMCHOME/digital/Front_End/verilog/tphn28hpcpgv18_110a/tphn28hpcpgv18.v
|
||||
../../lib/tcbn28hpcplusbwp7t35p140.v
|
||||
../../syn/current/outputs/xyz_chip_top.syn.v
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
../../rtl/define/chip_define.v
|
||||
../../lib/tphn28hpcpgv18.v
|
||||
../../lib/tsdn28hpcpuhdb4096x128m4mw_170a_ffg0p99v0c.v
|
||||
../../rtl/io/iopad.v
|
||||
../../rtl/systemregfile/systemregfile.v
|
||||
../../rtl/dacif/dacif.v
|
||||
../../rtl/fifo/syn_fwft_fifo.v
|
||||
../../rtl/dac_regfile/dac_regfile.v
|
||||
../../rtl/lvds/ulink_rx.sv
|
||||
../../rtl/rstgen/rst_gen_unit.v
|
||||
../../rtl/rstgen/rst_sync.v
|
||||
../../rtl/comm/sirv_gnrl_xchecker.v
|
||||
../../rtl/comm/pulse_generator.sv
|
||||
../../rtl/comm/sirv_gnrl_dffs.v
|
||||
../../rtl/comm/syncer.v
|
||||
../../rtl/comm/ramp_gen.v
|
||||
../../rtl/memory/tsmc_dpram.v
|
||||
../../rtl/memory/sram_if.sv
|
||||
../../rtl/memory/sram_dmux.sv
|
||||
../../rtl/memory/dpram.v
|
||||
../../rtl/memory/bhv_spram.v
|
||||
../../rtl/memory/spram.v
|
||||
../../rtl/clk/clk_regfile.v
|
||||
../../rtl/awg/awg_top.sv
|
||||
../../rtl/awg/awg_ctrl.v
|
||||
../../rtl/dem/DEM_PhaseSync_4008.sv
|
||||
../../rtl/dem/DA4008_DEM_Parallel_PRBS_1CH.v
|
||||
../../rtl/dem/DA4008_DEM_Parallel_PRBS_64CH.v
|
||||
../../rtl/top/da4008_chip_top.sv
|
||||
../../rtl/top/digital_top.sv
|
||||
../../rtl/spi/spi_bus_decoder.sv
|
||||
../../rtl/spi/spi_slave.v
|
||||
../../rtl/spi/spi_pll.v
|
||||
../../rtl/spi/spi_sys.v
|
||||
../../model/clock_tb.v
|
||||
../../model/spi_if.sv
|
||||
../../model/clk_gen.v
|
||||
../../model/DEM_Reverse_64CH.v
|
||||
../../model/DEM_Reverse.v
|
||||
../../model/reset_tb.v
|
||||
../../model/DW_stream_sync.v
|
||||
../../model/DW_reset_sync.v
|
||||
../../model/DW_sync.v
|
||||
../../model/DW_pulse_sync.v
|
||||
../../sim/chip_top/TB.sv
|
||||
../../rtl/define/chip_undefine.v
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
#!/bin/csh
|
||||
|
||||
# Set the directory to be processed (default is the current directory)
|
||||
set case_dir = "../../case/config"
|
||||
|
||||
# If a directory is provided as a parameter, use that directory.
|
||||
#if ($#argv > 0) then
|
||||
# set case_dir = $argv
|
||||
#endif
|
||||
|
||||
# Check if two directories and a log file are provided as parameters.
|
||||
if ( $#argv != 1 ) then
|
||||
echo "Usage: $0 SIM"
|
||||
exit 1
|
||||
endif
|
||||
|
||||
set SIM = $1
|
||||
|
||||
# Initialize Counter
|
||||
set dir_count = 1
|
||||
|
||||
# List all directories, and print their sequence numbers.
|
||||
echo "Listing directories in $case_dir :"
|
||||
foreach dir (`ls -d $case_dir/*/`)
|
||||
# set filelist = `basename $file .txt`
|
||||
echo "$dir_count : $dir"
|
||||
# echo "$count : $filelist"
|
||||
@ dir_count++
|
||||
end
|
||||
|
||||
|
||||
# Obtain the sequence number input by the user from the command line.
|
||||
echo -n "Enter the start number: "
|
||||
set start = $<
|
||||
echo -n "Enter the end number: "
|
||||
set end = $<
|
||||
echo -n "Whether save sim files? 1: save; 0: delete."
|
||||
echo -n "Enter your choice: "
|
||||
set save = $<
|
||||
if ("$save" == "") then
|
||||
set save = 0
|
||||
endif
|
||||
|
||||
make -s comp WAVE=$save
|
||||
|
||||
if ( $start < 1 || $end > $dir_count - 1 || $start > $end ) then
|
||||
echo "Invalid directory range. Please enter a valid range."
|
||||
exit 1
|
||||
endif
|
||||
|
||||
set selected_dirs = ()
|
||||
@ dir_index = 1
|
||||
foreach dir (`ls -d $case_dir/*/`)
|
||||
if ( $dir_index >= $start && $dir_index <= $end ) then
|
||||
set selected_dirs = ($selected_dirs $dir)
|
||||
endif
|
||||
@ dir_index++
|
||||
end
|
||||
|
||||
foreach folder ($selected_dirs)
|
||||
echo "Processing folder: $folder"
|
||||
|
||||
# 获取文件夹中的所有 TXT 文件
|
||||
set file_list = ($folder/*.txt)
|
||||
set txt_count = $#file_list
|
||||
# 产生对应的文件夹地址
|
||||
set gather_folder = `echo $folder | sed 's|/config/|/gather/|'`
|
||||
set result_folder = `echo $folder | sed 's|../../case/config/|result/|g'`
|
||||
set coverage_folder = `echo $folder | sed 's|../../case/config/|coverage/|g'`
|
||||
|
||||
# 打印 result_folder 的值
|
||||
echo "Result folder: $result_folder"
|
||||
mkdir -p $gather_folder
|
||||
# 检查是否有 TXT 文件
|
||||
if ( $#file_list == 0 ) then
|
||||
echo "No .txt files found in $folder. Skipping..."
|
||||
continue
|
||||
endif
|
||||
mkdir -p $result_folder
|
||||
# TB从这些文件中读取case,result等文件的路径
|
||||
set temp_files = ("case_temp.txt" "data_temp.txt" "result_temp.txt")
|
||||
# 遍历文件列表,检查是否存在,不存在则创建,这样git就不用追踪这些txt文件了
|
||||
foreach file ($temp_files)
|
||||
if ( ! -e $file ) then
|
||||
touch $file
|
||||
endif
|
||||
end
|
||||
#遍历文件夹中的所有 TXT 文件
|
||||
@ i = 1
|
||||
foreach file ($file_list)
|
||||
# echo "Processing file: $file"
|
||||
# set file_list = ($case_dir/*.txt)
|
||||
|
||||
set rstdir = "./data_$SIM"
|
||||
mkdir -p $rstdir
|
||||
|
||||
while ( $i <= $txt_count )
|
||||
set filename = `basename $file_list[$i] .txt`
|
||||
set filen = `basename $file_list[$i]`
|
||||
set dirname = `dirname $file_list[$i]`
|
||||
# 拼接目标文件路径
|
||||
set gather_file = "$gather_folder/$filename.txt"
|
||||
set result_file = "$result_folder/$filename.txt"
|
||||
# 创建result等相关文件
|
||||
set file_lists = ($result_file)
|
||||
# 遍历文件列表,检查并创建文件
|
||||
foreach file ($file_lists)
|
||||
touch $file
|
||||
echo "" > $file
|
||||
# 输出创建文件的状态
|
||||
if ( $status == 0 ) then
|
||||
echo "File $file created successfully."
|
||||
else
|
||||
echo "Failed to create file $file."
|
||||
endif
|
||||
end
|
||||
# Create directories corresponding to filenames
|
||||
set newdir = "./work_$SIM/$filename"
|
||||
mkdir -p $newdir
|
||||
# echo $status
|
||||
if ( $status == 0 ) then
|
||||
echo "Directory $newdir created successfully."
|
||||
else
|
||||
echo "Failed to create directory $newdir."
|
||||
endif
|
||||
# echo "Directory $newdir created."
|
||||
# Copy the simv file to the corresponding folder.
|
||||
echo "Copy the simv file to the $newdir folder."
|
||||
\cp -f ./simv $newdir/
|
||||
\cp -rf simv.daidir $newdir/
|
||||
|
||||
\cp -f ./backup/Makefile $newdir/
|
||||
\cp -f ./backup/filelist_syn.f $newdir/
|
||||
\cp -f ./backup/filelist_vlg.f $newdir/
|
||||
|
||||
echo "" > ./case_temp.txt
|
||||
echo "" > ./data_temp.txt
|
||||
echo "" > ./result_temp.txt
|
||||
echo " ../../$file_list[$i]" >> case_temp.txt
|
||||
echo " ../../${result_file}" >> result_temp.txt
|
||||
set result = "data_$SIM"
|
||||
|
||||
set new_dir = `echo "$dirname" | sed 's|../../case/config|'$result'|'`
|
||||
mkdir -p $new_dir
|
||||
set result = "$new_dir/$filen"
|
||||
touch $result
|
||||
|
||||
echo "../../$result" >> data_temp.txt
|
||||
cd $newdir/
|
||||
# Run "run" command in makefile
|
||||
./simv -l sim.log -cm line+cond+fsm+tgl+branch -cm_dir ../../$coverage_folder -cm_name $filename "+ENABLE_FSDB=$save"
|
||||
cd ../../
|
||||
if ( $save == 0 ) then
|
||||
rm -rf $newdir
|
||||
endif
|
||||
@ i++
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
|
||||
WAVE ?= 0
|
||||
|
||||
SIM = RTL
|
||||
|
||||
folder = simv
|
||||
|
||||
ifeq ($(WAVE),1)
|
||||
WAVE_OPTS = -debug_access+all -debug_region+cell+encrypt -P $(NOVAS_HOME)/share/PLI/VCS/linux64/novas_new_dumper.tab $(NOVAS_HOME)/share/PLI/VCS/linux64/pli.a +define+DUMP_FSDB
|
||||
WAVE_SIM_OPTS = -fsdbDumpfile=sim.fsdb
|
||||
else
|
||||
WAVE_OPTS = -debug_access+pp
|
||||
endif
|
||||
|
||||
ifeq ($(SIM),PostPr)
|
||||
VCS = vcs -full64 -sverilog -Mupdate +lint=TFIPC-L +v2k +warn=noSDFCOM_IWSBA,noNTCDNC -notice +mindelays +tchk+edge+warn +neg_tchk -negdelay +overlap +sdfverbose -sdfretain +optconfigfile+notimingcheck.cfg -override_timescale=1ns/1ps -debug_access+all $(WAVE_OPTS) -lca -q -l compile.log -cm line+cond+fsm+tgl+branch -cm_dir ./coverage/simv.vdb |tee
|
||||
else
|
||||
VCS = vcs -full64 -j8 -sverilog +lint=TFIPC-L +v2k $(WAVE_OPTS) -lca -q -timescale=1ns/1ps +nospecify -l compile.log -cm line+cond+fsm+tgl+branch -cm_dir ./coverage/simv.vdb
|
||||
endif
|
||||
|
||||
ifeq ($(SIM),PostPr)
|
||||
post_dir = ./data_PostPr
|
||||
else
|
||||
post_dir = ./data_PostSyn
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(SIM),PostSyn)
|
||||
FileList = filelist_syn.f
|
||||
else
|
||||
ifeq ($(SIM),PostPr)
|
||||
FileList = filelist_pr.f
|
||||
else
|
||||
FileList = filelist_vlg.f
|
||||
endif
|
||||
endif
|
||||
|
||||
SIMV = ./simv sync:busywait -Xdprof=timeline $(WAVE_SIM_OPTS) -l |tee sim.log
|
||||
|
||||
all:comp run
|
||||
|
||||
comp:
|
||||
${VCS} -f $(FileList) +incdir+./../../rtl/define +incdir+./../../rtl/qubitmcu +incdir+./../../model
|
||||
|
||||
run:
|
||||
${SIMV}
|
||||
|
||||
dbg:
|
||||
verdi -sverilog -f $(FileList) -top TB -ssf *.fsdb -nologo &
|
||||
|
||||
clean:
|
||||
rm -rf DVE* simv* *log ucli.key verdiLog urgReport csrc novas.* *fsdb* *.dat *.daidir *.vdb *~
|
||||
|
||||
compare:
|
||||
./compare_files.csh ${post_dir} ./data_RTL ./compare.txt
|
||||
|
||||
regress:
|
||||
./regress.csh $(SIM)
|
||||
|
||||
rmwork:
|
||||
rm -rf ./work*
|
||||
|
||||
rmdata:
|
||||
rm -rf ./data*
|
||||
cov:
|
||||
verdi -cov -covdir coverage/merged.vdb &
|
||||
cov_d:
|
||||
dve -full64 -covdir coverage/*.vdb &
|
||||
merge:
|
||||
urg -full64 -dbname coverage/merged.vdb -flex_merge union -dir coverage/simv.vdb -parallel -maxjobs 64&
|
||||
merge_i:
|
||||
urg -full64 -flex_merge union -dir coverage/merged.vdb -dir coverage/$(folder) -dbname coverage/merged.vdb -parallel -maxjobs 64&
|
||||
|
|
@ -0,0 +1,479 @@
|
|||
`timescale 1ns/1ps
|
||||
|
||||
module TB;
|
||||
|
||||
// ====================================================
|
||||
// Parameters
|
||||
// ====================================================
|
||||
parameter FIFO_DEPTH = 64;
|
||||
parameter SCRAMBLER_SEED = 32'hFFFFFFFF;
|
||||
parameter CLK_PERIOD = 10; // 10ns
|
||||
parameter PATN_COUNT = 20'd10; // Training match count
|
||||
parameter TAP_STEP = 3'd3; // Delay adjustment step
|
||||
|
||||
// ====================================================
|
||||
// Constants (moved to top for visibility)
|
||||
// ====================================================
|
||||
localparam [31:0] TRAINING_PATN = 32'h68666E6C; // "hfnl"
|
||||
localparam [31:0] TRAINING_EXIT = 32'h65786974; // "exit"
|
||||
localparam [31:0] FRAME_HEADER = 32'hBCBCBCBC;
|
||||
|
||||
initial begin
|
||||
$fsdbAutoSwitchDumpfile(500, "./verdplus.fsdb", 1000000);
|
||||
$fsdbDumpvars();
|
||||
$fsdbDumpMDA();
|
||||
end
|
||||
|
||||
// ====================================================
|
||||
// Signals
|
||||
// ====================================================
|
||||
logic clk;
|
||||
logic rst_n;
|
||||
logic [3:0] serial_in;
|
||||
logic [19:0] patn_count;
|
||||
logic [2:0] tap_step;
|
||||
logic link_down;
|
||||
logic [2:0] delay_tap;
|
||||
logic [12:0] wr_addr;
|
||||
logic [511:0] wr_data;
|
||||
logic wr_en;
|
||||
logic [63:0] byte_mask;
|
||||
logic crc_error;
|
||||
logic [2 :0] tap_adj_mask = 3'b111; // Delay adjustment mask
|
||||
logic [0 :0] tap_force = 1'b0 ; // Delay force to tap_step
|
||||
logic tap_adj_req ;
|
||||
logic frame_done ;
|
||||
logic [31 :0] train_status ;
|
||||
logic [31 :0] frame_status ;
|
||||
logic always_on = 1'b0 ;
|
||||
logic prefilling ;
|
||||
logic prefill_start;
|
||||
|
||||
// Added for scrambler test
|
||||
logic descram_en;
|
||||
logic [31:0] lfsr_lane[0:3]; // 4 independent LFSRs for scrambling
|
||||
logic train_ready;
|
||||
logic force_train; // Force Training
|
||||
// ====================================================
|
||||
// DUT Instance
|
||||
// ====================================================
|
||||
ulink_rx #(
|
||||
.FIFO_DEPTH ( FIFO_DEPTH )
|
||||
,.SCRAMBLER_SEED ( SCRAMBLER_SEED )
|
||||
) dut (
|
||||
.clk ( clk )
|
||||
,.rst_n ( rst_n )
|
||||
,.serial_in ( serial_in )
|
||||
,.patn_count ( patn_count )
|
||||
,.tap_step ( tap_step )
|
||||
,.descram_en ( descram_en ) // now variable
|
||||
,.link_down ( link_down )
|
||||
,.delay_tap ( delay_tap )
|
||||
,.wr_addr ( wr_addr )
|
||||
,.wr_data ( wr_data )
|
||||
,.wr_en ( wr_en )
|
||||
,.byte_mask ( byte_mask )
|
||||
,.crc_error ( crc_error )
|
||||
,.tap_adj_mask ( tap_adj_mask )
|
||||
,.tap_force ( tap_force )
|
||||
,.tap_adj_req ( tap_adj_req )
|
||||
,.frame_done ( frame_done )
|
||||
,.train_status ( train_status )
|
||||
,.frame_status ( frame_status )
|
||||
,.always_on ( always_on )
|
||||
,.prefilling ( prefilling )
|
||||
,.prefill_start ( prefill_start )
|
||||
,.train_ready ( train_ready )
|
||||
,.force_train ( force_train )
|
||||
);
|
||||
|
||||
// ====================================================
|
||||
// Clock Generation
|
||||
// ====================================================
|
||||
initial begin
|
||||
clk = 0;
|
||||
forever #(CLK_PERIOD/2) clk = ~clk;
|
||||
end
|
||||
|
||||
// ====================================================
|
||||
// Tasks for Stimulus Generation
|
||||
// ====================================================
|
||||
|
||||
// Reset task
|
||||
task reset;
|
||||
begin
|
||||
rst_n = 0;
|
||||
repeat(5) @(posedge clk);
|
||||
rst_n = 1;
|
||||
repeat(2) @(posedge clk);
|
||||
end
|
||||
endtask
|
||||
|
||||
// Send one 128-bit block over 32 cycles
|
||||
task send_block;
|
||||
input [127:0] block;
|
||||
begin
|
||||
integer i;
|
||||
for (i = 31; i >= 0; i = i - 1) begin
|
||||
serial_in[0] = block[i];
|
||||
serial_in[1] = block[32 + i];
|
||||
serial_in[2] = block[64 + i];
|
||||
serial_in[3] = block[96 + i];
|
||||
@(posedge clk);
|
||||
#0.1;
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
// Send multiple identical blocks
|
||||
task send_blocks;
|
||||
input [127:0] block;
|
||||
input integer count;
|
||||
begin
|
||||
repeat(count) send_block(block);
|
||||
end
|
||||
endtask
|
||||
|
||||
// Send a sequence of 32-bit words (packed into 128-bit blocks)
|
||||
task send_words;
|
||||
input integer num_words;
|
||||
input [31:0] words[0:255];
|
||||
begin
|
||||
integer word_idx;
|
||||
integer j;
|
||||
reg [127:0] block;
|
||||
word_idx = 0;
|
||||
while (word_idx < num_words) begin
|
||||
block = 128'h0;
|
||||
for (j = 0; j < 4; j = j + 1) begin
|
||||
if (word_idx < num_words) begin
|
||||
block[32*j +: 32] = words[word_idx];
|
||||
word_idx = word_idx + 1;
|
||||
end
|
||||
end
|
||||
send_block(block);
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
// ====================================================
|
||||
// Scrambler tasks (used when descram_en=1)
|
||||
// ====================================================
|
||||
|
||||
// Original scrambler (all lanes scrambled)
|
||||
task scramble_block;
|
||||
input [127:0] original;
|
||||
output [127:0] scrambled;
|
||||
integer i;
|
||||
reg [31:0] lane_word;
|
||||
begin
|
||||
scrambled = 128'h0;
|
||||
for (i = 0; i < 4; i = i + 1) begin
|
||||
lane_word = original[32*i +: 32];
|
||||
scrambled[32*i +: 32] = lane_word ^ lfsr_lane[i];
|
||||
// Update LFSR: feedback = lfsr[31]^lfsr[30]^lfsr[29]^lfsr[28]
|
||||
lfsr_lane[i] = {lfsr_lane[i][30:0],
|
||||
lfsr_lane[i][31] ^ lfsr_lane[i][30] ^
|
||||
lfsr_lane[i][29] ^ lfsr_lane[i][28]};
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
// New scrambler with per-lane mask (1=scramble that lane)
|
||||
task scramble_block_masked;
|
||||
input [127:0] original;
|
||||
input [3:0] mask; // 1=scramble this lane
|
||||
output [127:0] scrambled;
|
||||
integer i;
|
||||
reg [31:0] lane_word;
|
||||
begin
|
||||
scrambled = 128'h0;
|
||||
for (i = 0; i < 4; i = i + 1) begin
|
||||
lane_word = original[32*i +: 32];
|
||||
if (mask[i]) begin
|
||||
scrambled[32*i +: 32] = lane_word ^ lfsr_lane[i];
|
||||
// Update LFSR only for scrambled lanes
|
||||
lfsr_lane[i] = {lfsr_lane[i][30:0],
|
||||
lfsr_lane[i][31] ^ lfsr_lane[i][30] ^
|
||||
lfsr_lane[i][29] ^ lfsr_lane[i][28]};
|
||||
end else begin
|
||||
scrambled[32*i +: 32] = lane_word;
|
||||
// No LFSR update for unscrambled lanes
|
||||
end
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
// ====================================================
|
||||
// CRC32 Computation Functions
|
||||
// ====================================================
|
||||
function automatic [31:0] crc32_next;
|
||||
input [31:0] crc;
|
||||
input [31:0] data;
|
||||
reg [31:0] new_crc;
|
||||
reg b;
|
||||
integer i;
|
||||
begin
|
||||
new_crc = crc;
|
||||
for (i = 0; i < 32; i = i + 1) begin
|
||||
b = new_crc[31] ^ data[31-i];
|
||||
new_crc = {new_crc[30:0], 1'b0};
|
||||
if (b) new_crc = new_crc ^ 32'h04C11DB7;
|
||||
end
|
||||
crc32_next = new_crc;
|
||||
end
|
||||
endfunction
|
||||
|
||||
function automatic [31:0] crc32_compute;
|
||||
input [31:0] words[0:255];
|
||||
input integer num;
|
||||
reg [31:0] crc;
|
||||
integer i;
|
||||
begin
|
||||
crc = 32'hFFFFFFFF;
|
||||
for (i = 0; i < num; i = i + 1) begin
|
||||
crc = crc32_next(crc, words[i]);
|
||||
end
|
||||
crc32_compute = crc;
|
||||
end
|
||||
endfunction
|
||||
|
||||
// ====================================================
|
||||
// Test Variables (module level)
|
||||
// ====================================================
|
||||
integer data_words;
|
||||
reg [31:0] frame_words[0:255];
|
||||
integer frame_len;
|
||||
integer i;
|
||||
// ====================================================
|
||||
// Test Sequence
|
||||
// ====================================================
|
||||
initial begin
|
||||
// Initialize
|
||||
serial_in = 4'h0;
|
||||
patn_count = PATN_COUNT;
|
||||
tap_step = TAP_STEP;
|
||||
descram_en = 0; // default disabled
|
||||
force_train = 0;
|
||||
|
||||
$display("========================================");
|
||||
$display("Testbench started at %0t", $time);
|
||||
$display("========================================");
|
||||
|
||||
reset();
|
||||
wait(prefill_start == 1);
|
||||
repeat(10) @(posedge clk);
|
||||
prefilling = 1;
|
||||
repeat(100) @(posedge clk);
|
||||
prefilling = 0;
|
||||
// -------------------------------------------------
|
||||
// Phase 1: Link Training (successful)
|
||||
// -------------------------------------------------
|
||||
$display("Phase 1: Training with correct patterns...");
|
||||
|
||||
send_blocks({4{TRAINING_PATN}}, PATN_COUNT - 0);
|
||||
send_blocks({4{TRAINING_EXIT}}, 1);
|
||||
|
||||
wait(dut.u_train.train_ready == 1);
|
||||
$display("Link ready at %0t", $time);
|
||||
|
||||
// -------------------------------------------------
|
||||
// Phase 2: Send a correct frame
|
||||
// -------------------------------------------------
|
||||
$display("Phase 2: Sending a correct frame...");
|
||||
|
||||
data_words = 20;
|
||||
frame_len = 2 + data_words + 1;
|
||||
|
||||
frame_words[0] = FRAME_HEADER;
|
||||
frame_words[1] = (32'h1235 << 16) | data_words;
|
||||
|
||||
for (i = 0; i < data_words; i = i + 1) begin
|
||||
frame_words[2+i] = 32'hA0000000 + i;
|
||||
end
|
||||
|
||||
// Compute CRC over addr_len and data (1 + data_words words)
|
||||
begin
|
||||
reg [31:0] crc_tmp[0:255];
|
||||
integer k;
|
||||
for (k = 0; k < 1 + data_words; k = k + 1) begin
|
||||
crc_tmp[k] = frame_words[1 + k];
|
||||
end
|
||||
frame_words[2 + data_words] = crc32_compute(crc_tmp, 1 + data_words);
|
||||
end
|
||||
|
||||
send_words(frame_len, frame_words);
|
||||
|
||||
fork
|
||||
begin
|
||||
@(posedge wr_en);
|
||||
$display("Write detected: addr=%0d data=%h mask=%h", wr_addr, wr_data, byte_mask);
|
||||
if (wr_addr !== 13'h123) $error("Unexpected write address: %0d", wr_addr);
|
||||
if (byte_mask[31:0] !== 32'hFFFF_0000) $error("Byte mask mismatch: %h", byte_mask);
|
||||
if (byte_mask[63:32] !== 32'hFFFF_FFFF) $error("Byte mask high part not zero: %h", byte_mask[63:32]);
|
||||
$display("Correct frame write verified.");
|
||||
end
|
||||
join_none
|
||||
|
||||
repeat(100) @(posedge clk);
|
||||
|
||||
// -------------------------------------------------
|
||||
// Phase 3: Send a frame with bad CRC
|
||||
// -------------------------------------------------
|
||||
$display("Phase 3: Sending a frame with bad CRC...");
|
||||
|
||||
frame_words[2+data_words] = ~frame_words[2+data_words];
|
||||
send_words(frame_len, frame_words);
|
||||
|
||||
@(posedge crc_error);
|
||||
$display("CRC error detected at %0t", $time);
|
||||
repeat(10) @(posedge clk);
|
||||
if (link_down) $display("Link down as expected.");
|
||||
else $error("Link not down after CRC error.");
|
||||
|
||||
// -------------------------------------------------
|
||||
// Phase 4: Re-train and send another correct frame
|
||||
// -------------------------------------------------
|
||||
$display("Phase 4: Re-training...");
|
||||
|
||||
send_blocks({4{TRAINING_PATN}}, PATN_COUNT - 0);
|
||||
send_blocks({4{TRAINING_EXIT}}, 1);
|
||||
|
||||
wait(dut.u_train.train_ready == 1);
|
||||
$display("Link ready again.");
|
||||
|
||||
// Compute CRC over addr_len and data (1 + data_words words)
|
||||
begin
|
||||
reg [31:0] crc_tmp[0:255];
|
||||
integer k;
|
||||
for (k = 0; k < 1 + data_words; k = k + 1) begin
|
||||
crc_tmp[k] = frame_words[1 + k];
|
||||
end
|
||||
frame_words[2 + data_words] = crc32_compute(crc_tmp, 1 + data_words);
|
||||
end
|
||||
send_words(frame_len, frame_words);
|
||||
|
||||
repeat(100) @(posedge clk);
|
||||
|
||||
// -------------------------------------------------
|
||||
// Phase 5: Test delay_tap adjustment on match failure
|
||||
// -------------------------------------------------
|
||||
$display("Phase 5: Testing delay_tap adjustment...");
|
||||
|
||||
force_train = 1;
|
||||
repeat(1) @(posedge clk);
|
||||
force_train = 0;
|
||||
send_blocks(128'h0, 5);
|
||||
repeat(200) @(posedge clk);
|
||||
$display("Final delay_tap = %0d", delay_tap);
|
||||
|
||||
// -------------------------------------------------
|
||||
// Phase 6: Test with scrambler enabled (header not scrambled)
|
||||
// -------------------------------------------------
|
||||
$display("Phase 6: Testing with descrambler enabled (header not scrambled)...");
|
||||
|
||||
// Reset and train with descram_en=0 (training patterns are not scrambled)
|
||||
descram_en = 0;
|
||||
force_train = 1;
|
||||
repeat(1) @(posedge clk);
|
||||
force_train = 0;
|
||||
send_blocks({4{TRAINING_PATN}}, PATN_COUNT - 0);
|
||||
send_blocks({4{TRAINING_EXIT}}, 1);
|
||||
|
||||
wait(dut.u_train.train_ready == 1);
|
||||
$display("Link ready for scrambled data.");
|
||||
|
||||
// Enable descrambler in DUT and initialize LFSRs for transmission
|
||||
descram_en = 1;
|
||||
for (i = 0; i < 4; i = i + 1) lfsr_lane[i] = SCRAMBLER_SEED;
|
||||
|
||||
// Construct a simple frame (small data length)
|
||||
data_words = 10;
|
||||
frame_len = 2 + data_words + 1;
|
||||
|
||||
frame_words[0] = FRAME_HEADER;
|
||||
frame_words[1] = (32'h1234 << 16) | data_words; // base_addr=0x1234, offset=0, len=10
|
||||
|
||||
for (i = 0; i < data_words; i = i + 1) begin
|
||||
frame_words[2+i] = 32'hB0000000 + i; // different pattern from Phase 2
|
||||
end
|
||||
|
||||
// Compute CRC over addr_len and data (1 + data_words words)
|
||||
begin
|
||||
reg [31:0] crc_tmp[0:255];
|
||||
integer k;
|
||||
for (k = 0; k < 1 + data_words; k = k + 1) begin
|
||||
crc_tmp[k] = frame_words[1 + k];
|
||||
end
|
||||
frame_words[2 + data_words] = crc32_compute(crc_tmp, 1 + data_words);
|
||||
end
|
||||
|
||||
// Now scramble each 128-bit block and send
|
||||
begin
|
||||
integer word_idx;
|
||||
integer j;
|
||||
integer block_num;
|
||||
reg [127:0] orig_block, scrambled_block;
|
||||
reg [3:0] block_mask;
|
||||
word_idx = 0;
|
||||
block_num = 0;
|
||||
while (word_idx < frame_len) begin
|
||||
orig_block = 128'h0;
|
||||
// Fill block with up to 4 words, pad with 0 if needed
|
||||
for (j = 0; j < 4; j = j + 1) begin
|
||||
if (word_idx < frame_len) begin
|
||||
orig_block[32*j +: 32] = frame_words[word_idx];
|
||||
word_idx = word_idx + 1;
|
||||
end else begin
|
||||
orig_block[32*j +: 32] = 32'h0; // pad with 0
|
||||
end
|
||||
end
|
||||
// Determine mask: first block leaves lane0 unscrambled (header), others all scrambled
|
||||
block_mask = (block_num == 0) ? 4'b1110 : 4'b1111;
|
||||
scramble_block_masked(orig_block, block_mask, scrambled_block);
|
||||
send_block(scrambled_block);
|
||||
block_num = block_num + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// Monitor writes
|
||||
fork
|
||||
begin
|
||||
@(posedge wr_en);
|
||||
$display("Scrambled test write: addr=%0d data=%h mask=%h", wr_addr, wr_data, byte_mask);
|
||||
end
|
||||
join_none
|
||||
|
||||
repeat(200) @(posedge clk);
|
||||
|
||||
// Check that no CRC error happened
|
||||
if (crc_error) $error("CRC error in scrambled test");
|
||||
else $display("Scrambled test passed (no CRC error).");
|
||||
|
||||
// Disable scrambler for rest of test
|
||||
descram_en = 0;
|
||||
|
||||
// -------------------------------------------------
|
||||
// End of test
|
||||
// -------------------------------------------------
|
||||
repeat(50) @(posedge clk);
|
||||
$display("========================================");
|
||||
$display("Testbench finished at %0t", $time);
|
||||
$display("========================================");
|
||||
$finish;
|
||||
end
|
||||
|
||||
// ====================================================
|
||||
// Monitor and Assertions
|
||||
// ====================================================
|
||||
always @(posedge clk) begin
|
||||
if (wr_en) $display("WRITE: addr=%0d data=%h mask=%h", wr_addr, wr_data, byte_mask);
|
||||
if (crc_error) $display("CRC_ERROR pulse at %0t", $time);
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (dut.u_train.train_ready && link_down)
|
||||
$error("Inconsistent state: train_ready and link_down both high");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
../../rtl/comm/sirv_gnrl_xchecker.v
|
||||
../../rtl/comm/sirv_gnrl_dffs.v
|
||||
../../rtl/memory/spram.v
|
||||
../../rtl/memory/bhv_spram.v
|
||||
../../rtl/fifo/syn_fwft_fifo.v
|
||||
../../rtl/lvds/ulink_rx.sv
|
||||
../../sim/lvds/TB.sv
|
||||
Loading…
Reference in New Issue