Skip to content

Commit 579859a

Browse files
Merge pull request #26 from muhammadhamza15/mhamza_dev
MIPI Primitives updates
2 parents 0e56e28 + 58c49e3 commit 579859a

File tree

9 files changed

+528
-6
lines changed

9 files changed

+528
-6
lines changed

models_internal/verilog/MIPI_RX.v

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
`timescale 1ns/1ps
2+
`celldefine
3+
//
4+
// MIPI_RX simulation model
5+
// MIPI Receiver
6+
//
7+
// Copyright (c) 2023 Rapid Silicon, Inc. All rights reserved.
8+
//
9+
10+
module MIPI_RX #(
11+
parameter WIDTH = 4, // Width of input data to serializer (3-10)
12+
parameter EN_IDLY = "FALSE", // True or False
13+
parameter DELAY = 0 // Fixed TAP delay value (0-63)
14+
) (
15+
input RST, // Active-low, asynchronous reset
16+
input RX_CLK, // MIPI RX_IO clock input, PLL_CLK
17+
input PLL_LOCK, // PLL lock input
18+
input CLK_IN, // Fabric core clock input
19+
input RX_DP, // MIPI RX Data Positive input From I_BUF
20+
input RX_DN, // MIPI RX Data Negative input from I_BUF
21+
input HS_EN, // EN HS Data input (From Fabric). Active high signal. This is a common signal between MIPI RX/TX interface.
22+
input LP_EN, // EN LP Data input (From Fabric). This is a common signal between MIPI RX/TX interface.
23+
input RX_TERM_EN, // EN Differential Termination
24+
input BITSLIP_ADJ, // BITSLIP_ADJ input from Fabric
25+
input DLY_LOAD, // Delay load input, from Fabric
26+
input DLY_ADJ, // Delay adjust input, from Fabric
27+
input DLY_INCDEC, // Delay increment / decrement input, from Fabric
28+
output [5:0] DLY_TAP_VALUE, // Delay tap value output to fabric
29+
output [WIDTH-1:0] HS_RX_DATA, // HS RX Data output to Fabric
30+
output HS_RXD_VALID, // HS RX Parallel DATA is VALID
31+
output RX_OE, // IBUF OE signal for MIPI I_BUF
32+
output LP_RX_DP, // LP RX Data positive output to the Fabric
33+
output LP_RX_DN // LP RX Data negative output to the Fabric
34+
);
35+
36+
37+
wire i_delay_out;
38+
wire rx_dp_delay;
39+
wire rx_dn_delay;
40+
wire rx_dp;
41+
wire rx_dn;
42+
43+
I_DELAY # (
44+
.DELAY(DELAY)
45+
)
46+
I_DELAY_inst (
47+
.I(RX_DP),
48+
.DLY_LOAD(DLY_LOAD),
49+
.DLY_ADJ(DLY_ADJ),
50+
.DLY_INCDEC(DLY_INCDEC),
51+
.DLY_TAP_VALUE(DLY_TAP_VALUE),
52+
.CLK_IN(CLK_IN),
53+
.O(i_delay_out)
54+
);
55+
56+
I_SERDES # (
57+
.DATA_RATE("DDR"),
58+
.WIDTH(WIDTH),
59+
.DPA_MODE("NONE")
60+
)
61+
I_SERDES_inst (
62+
.D(rx_dp),
63+
.RST(RST),
64+
.BITSLIP_ADJ(BITSLIP_ADJ),
65+
.EN(HS_EN),
66+
.CLK_IN(CLK_IN),
67+
.CLK_OUT(CLK_OUT),
68+
.Q(HS_RX_DATA),
69+
.DATA_VALID(HS_RXD_VALID),
70+
.DPA_LOCK(),
71+
.DPA_ERROR(),
72+
.PLL_LOCK(PLL_LOCK),
73+
.PLL_CLK(RX_CLK)
74+
);
75+
76+
assign RX_OE= HS_EN | LP_EN;
77+
assign rx_dp_delay = (EN_IDLY=="FALSE")? RX_DP:i_delay_out;
78+
assign rx_dn_delay = (EN_IDLY=="FALSE")? RX_DN:~i_delay_out;
79+
80+
assign rx_dp = RX_TERM_EN?1'bz:RX_OE?rx_dp_delay:'b0;
81+
assign rx_dn = RX_TERM_EN?1'bz:RX_OE?rx_dn_delay:'b0;
82+
83+
assign LP_RX_DP = rx_dp;
84+
assign LP_RX_DN = rx_dn;
85+
86+
87+
always@(*)
88+
begin
89+
if(LP_EN && HS_EN)
90+
$fatal(1,"\nERROR: MIPI RX instance %m LP_EN and HS_EN can't be hight at same time");
91+
end
92+
93+
initial begin
94+
95+
if ((WIDTH < 3) || (WIDTH > 10)) begin
96+
$fatal(1,"MIPI_RX instance %m WIDTH set to incorrect value, %d. Values must be between 3 and 10.", WIDTH);
97+
end
98+
case(EN_IDLY)
99+
"TRUE" ,
100+
"FALSE": begin end
101+
default: begin
102+
$fatal(1,"\nError: MIPI_RX instance %m has parameter EN_IDLY set to %s. Valid values are TRUE, FALSE\n", EN_IDLY);
103+
end
104+
endcase
105+
106+
if ((DELAY < 0) || (DELAY > 63)) begin
107+
$fatal(1,"MIPI_RX instance %m DELAY set to incorrect value, %d. Values must be between 0 and 63.", DELAY);
108+
end
109+
110+
end
111+
112+
endmodule
113+
`endcelldefine

models_internal/verilog/MIPI_TX.v

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ O_DELAY_inst (
8686
end
8787
end
8888

89-
assign TX_DP = (EN_ODLY=="FALSE")? tx_dp:o_delay_dout;
90-
assign TX_DN = (EN_ODLY=="FALSE")? tx_dn:~o_delay_dout;
89+
assign TX_DP = TX_ODT_EN?1'bz:(EN_ODLY=="FALSE")? tx_dp:o_delay_dout;
90+
assign TX_DN = TX_ODT_EN?1'bz:(EN_ODLY=="FALSE")? tx_dn:~o_delay_dout;
9191

9292
// assign TX_DP = tx_dp;
9393
// assign TX_DN = tx_dn;
@@ -96,7 +96,9 @@ O_DELAY_inst (
9696
begin
9797
if(LP_EN && HS_EN)
9898
$fatal(1,"\nERROR: MIPI TX instance %m LP_EN and HS_EN can't be hight at same time");
99-
end initial begin
99+
end
100+
101+
initial begin
100102

101103
if ((WIDTH < 3) || (WIDTH > 10)) begin
102104
$fatal(1,"MIPI_TX instance %m WIDTH set to incorrect value, %d. Values must be between 3 and 10.", WIDTH);
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
2+
3+
wire i_delay_out;
4+
wire rx_dp_delay;
5+
wire rx_dn_delay;
6+
wire rx_dp;
7+
wire rx_dn;
8+
9+
I_DELAY # (
10+
.DELAY(DELAY)
11+
)
12+
I_DELAY_inst (
13+
.I(RX_DP),
14+
.DLY_LOAD(DLY_LOAD),
15+
.DLY_ADJ(DLY_ADJ),
16+
.DLY_INCDEC(DLY_INCDEC),
17+
.DLY_TAP_VALUE(DLY_TAP_VALUE),
18+
.CLK_IN(CLK_IN),
19+
.O(i_delay_out)
20+
);
21+
22+
I_SERDES # (
23+
.DATA_RATE("DDR"),
24+
.WIDTH(WIDTH),
25+
.DPA_MODE("NONE")
26+
)
27+
I_SERDES_inst (
28+
.D(rx_dp),
29+
.RST(RST),
30+
.BITSLIP_ADJ(BITSLIP_ADJ),
31+
.EN(HS_EN),
32+
.CLK_IN(CLK_IN),
33+
.CLK_OUT(CLK_OUT),
34+
.Q(HS_RX_DATA),
35+
.DATA_VALID(HS_RXD_VALID),
36+
.DPA_LOCK(),
37+
.DPA_ERROR(),
38+
.PLL_LOCK(PLL_LOCK),
39+
.PLL_CLK(RX_CLK)
40+
);
41+
42+
assign RX_OE= HS_EN | LP_EN;
43+
assign rx_dp_delay = (EN_IDLY=="FALSE")? RX_DP:i_delay_out;
44+
assign rx_dn_delay = (EN_IDLY=="FALSE")? RX_DN:~i_delay_out;
45+
46+
assign rx_dp = RX_TERM_EN?1'bz:RX_OE?rx_dp_delay:'b0;
47+
assign rx_dn = RX_TERM_EN?1'bz:RX_OE?rx_dn_delay:'b0;
48+
49+
assign LP_RX_DP = rx_dp;
50+
assign LP_RX_DN = rx_dn;
51+
52+
53+
always@(*)
54+
begin
55+
if(LP_EN && HS_EN)
56+
$fatal(1,"\nERROR: MIPI RX instance %m LP_EN and HS_EN can't be hight at same time");
57+
end
58+

models_internal/verilog/inc/MIPI_RX.pro.v

Whitespace-only changes.

models_internal/verilog/inc/MIPI_TX.inc.v

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ O_DELAY_inst (
5151
end
5252
end
5353

54-
assign TX_DP = (EN_ODLY=="FALSE")? tx_dp:o_delay_dout;
55-
assign TX_DN = (EN_ODLY=="FALSE")? tx_dn:~o_delay_dout;
54+
assign TX_DP = TX_ODT_EN?1'bz:(EN_ODLY=="FALSE")? tx_dp:o_delay_dout;
55+
assign TX_DN = TX_ODT_EN?1'bz:(EN_ODLY=="FALSE")? tx_dn:~o_delay_dout;
5656

5757
// assign TX_DP = tx_dp;
5858
// assign TX_DN = tx_dn;
@@ -61,4 +61,6 @@ O_DELAY_inst (
6161
begin
6262
if(LP_EN && HS_EN)
6363
$fatal(1,"\nERROR: MIPI TX instance %m LP_EN and HS_EN can't be hight at same time");
64-
end
64+
end
65+
66+
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
`timescale 1ns/1ps
2+
module MIPI_RX_tb;
3+
4+
// Parameters
5+
localparam WIDTH = 4 ;
6+
localparam EN_IDLY = "FALSE";
7+
localparam DELAY = 0;
8+
localparam phase = 0;
9+
10+
//Ports
11+
reg RST;
12+
reg RX_CLK;
13+
reg PLL_LOCK;
14+
reg CLK_IN;
15+
reg RX_DP;
16+
reg RX_DN;
17+
reg HS_EN;
18+
reg LP_EN;
19+
reg RX_TERM_EN;
20+
reg BITSLIP_ADJ;
21+
reg DLY_LOAD;
22+
reg DLY_ADJ;
23+
reg DLY_INCDEC;
24+
wire [5:0] DLY_TAP_VALUE;
25+
wire [WIDTH-1:0] HS_RX_DATA;
26+
wire HS_RXD_VALID;
27+
wire RX_OE;
28+
wire LP_RX_DP;
29+
wire LP_RX_DN;
30+
31+
real delay;
32+
33+
MIPI_RX # (
34+
.WIDTH(WIDTH),
35+
.EN_IDLY(EN_IDLY),
36+
.DELAY(DELAY)
37+
)
38+
MIPI_RX_inst (
39+
.RST(RST),
40+
.RX_CLK(RX_CLK),
41+
.PLL_LOCK(PLL_LOCK),
42+
.CLK_IN(CLK_IN),
43+
.RX_DP(RX_DP),
44+
.RX_DN(RX_DN),
45+
.HS_EN(HS_EN),
46+
.LP_EN(LP_EN),
47+
.RX_TERM_EN(RX_TERM_EN),
48+
.BITSLIP_ADJ(BITSLIP_ADJ),
49+
.DLY_LOAD(DLY_LOAD),
50+
.DLY_ADJ(DLY_ADJ),
51+
.DLY_INCDEC(DLY_INCDEC),
52+
.DLY_TAP_VALUE(DLY_TAP_VALUE),
53+
.HS_RX_DATA(HS_RX_DATA),
54+
.HS_RXD_VALID(HS_RXD_VALID),
55+
.RX_OE(RX_OE),
56+
.LP_RX_DP(LP_RX_DP),
57+
.LP_RX_DN(LP_RX_DN)
58+
);
59+
60+
always #0.2 RX_CLK = ! RX_CLK ; // 2.5 GHz
61+
always #0.8 CLK_IN = ! CLK_IN ;
62+
63+
initial
64+
begin
65+
CLK_IN=0;
66+
RX_CLK=0;
67+
PLL_LOCK=1;
68+
RST=0;
69+
DLY_LOAD=0;
70+
DLY_ADJ=0;
71+
DLY_INCDEC=0;
72+
RX_DP=0;
73+
HS_EN=0;
74+
LP_EN=0;
75+
BITSLIP_ADJ=0;
76+
RX_TERM_EN=0;
77+
delay=(phase==90)?0.1:(phase==180)?0.2:(phase==270)?0.3:0;
78+
repeat(2)@(posedge RX_CLK);
79+
RST=1;
80+
RX_DP=0;
81+
HS_EN=0;
82+
repeat(63)
83+
begin
84+
@(posedge RX_CLK);
85+
#(delay);
86+
HS_EN=1;
87+
RX_DP=1;
88+
@(posedge RX_CLK);
89+
#(delay);
90+
RX_DP=0;
91+
@(posedge RX_CLK);
92+
#(delay);
93+
RX_DP=1;
94+
@(posedge RX_CLK);
95+
#(delay);
96+
RX_DP=0;
97+
98+
end
99+
100+
fork
101+
begin
102+
repeat(20)
103+
begin
104+
@(posedge RX_CLK);
105+
#(delay);
106+
HS_EN=1;
107+
RX_DP=1;
108+
@(posedge RX_CLK);
109+
#(delay);
110+
RX_DP=0;
111+
@(posedge RX_CLK);
112+
#(delay);
113+
RX_DP=1;
114+
@(posedge RX_CLK);
115+
#(delay);
116+
RX_DP=0;
117+
end
118+
@(posedge RX_CLK);
119+
#(delay);
120+
RX_DP=1;
121+
@(posedge RX_CLK);
122+
#(delay);
123+
RX_DP=1;
124+
@(posedge RX_CLK);
125+
#(delay);
126+
RX_DP=0;
127+
@(posedge RX_CLK);
128+
#(delay);
129+
RX_DP=0;
130+
131+
@(posedge RX_CLK);
132+
#(delay);
133+
RX_DP=1;
134+
@(posedge RX_CLK);
135+
#(delay);
136+
RX_DP=1;
137+
@(posedge RX_CLK);
138+
#(delay);
139+
RX_DP=0;
140+
@(posedge RX_CLK);
141+
#(delay);
142+
RX_DP=1;
143+
end
144+
145+
begin
146+
// bitslip
147+
repeat(3)
148+
begin
149+
@(negedge CLK_IN);
150+
BITSLIP_ADJ=1;
151+
repeat(2)@(negedge CLK_IN);
152+
BITSLIP_ADJ=0;
153+
end
154+
end
155+
join_any
156+
#1000;
157+
$finish;
158+
159+
end
160+
161+
assign RX_DN = ~RX_DP;
162+
initial
163+
begin
164+
$dumpfile("waves.vcd");
165+
$dumpvars;
166+
end
167+
endmodule

0 commit comments

Comments
 (0)