first submit

This commit is contained in:
yangshenbo 2026-03-13 14:32:42 +08:00
commit ab2d1571bf
73 changed files with 24760 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,5 @@
00100000
00000004
0c00000a

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */
/* */

View File

@ -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 */
/* */

385
DA4008_V1.2/model/DW_sync.v Normal file
View File

@ -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 */
/* */

View File

@ -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

View File

@ -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

141
DA4008_V1.2/model/clk_gen.v Normal file
View File

@ -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

View File

@ -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```*/

71
DA4008_V1.2/model/glbl.v Normal file
View File

@ -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

View File

@ -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```*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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//}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

187
DA4008_V1.2/rtl/io/iopad.v Normal file
View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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
*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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&

View File

@ -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

View File

@ -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.

View File

@ -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&

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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&

479
DA4008_V1.2/sim/lvds/TB.sv Normal file
View File

@ -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

View File

@ -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