Skip to content

Commit

Permalink
Merge pull request #61 from muhammadhamza15/main
Browse files Browse the repository at this point in the history
MIPI Primitives
  • Loading branch information
muhammadhamza15 authored Sep 11, 2024
2 parents 0e56e28 + 579859a commit 072abcc
Show file tree
Hide file tree
Showing 9 changed files with 528 additions and 6 deletions.
113 changes: 113 additions & 0 deletions models_internal/verilog/MIPI_RX.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
`timescale 1ns/1ps
`celldefine
//
// MIPI_RX simulation model
// MIPI Receiver
//
// Copyright (c) 2023 Rapid Silicon, Inc. All rights reserved.
//

module MIPI_RX #(
parameter WIDTH = 4, // Width of input data to serializer (3-10)
parameter EN_IDLY = "FALSE", // True or False
parameter DELAY = 0 // Fixed TAP delay value (0-63)
) (
input RST, // Active-low, asynchronous reset
input RX_CLK, // MIPI RX_IO clock input, PLL_CLK
input PLL_LOCK, // PLL lock input
input CLK_IN, // Fabric core clock input
input RX_DP, // MIPI RX Data Positive input From I_BUF
input RX_DN, // MIPI RX Data Negative input from I_BUF
input HS_EN, // EN HS Data input (From Fabric). Active high signal. This is a common signal between MIPI RX/TX interface.
input LP_EN, // EN LP Data input (From Fabric). This is a common signal between MIPI RX/TX interface.
input RX_TERM_EN, // EN Differential Termination
input BITSLIP_ADJ, // BITSLIP_ADJ input from Fabric
input DLY_LOAD, // Delay load input, from Fabric
input DLY_ADJ, // Delay adjust input, from Fabric
input DLY_INCDEC, // Delay increment / decrement input, from Fabric
output [5:0] DLY_TAP_VALUE, // Delay tap value output to fabric
output [WIDTH-1:0] HS_RX_DATA, // HS RX Data output to Fabric
output HS_RXD_VALID, // HS RX Parallel DATA is VALID
output RX_OE, // IBUF OE signal for MIPI I_BUF
output LP_RX_DP, // LP RX Data positive output to the Fabric
output LP_RX_DN // LP RX Data negative output to the Fabric
);


wire i_delay_out;
wire rx_dp_delay;
wire rx_dn_delay;
wire rx_dp;
wire rx_dn;

I_DELAY # (
.DELAY(DELAY)
)
I_DELAY_inst (
.I(RX_DP),
.DLY_LOAD(DLY_LOAD),
.DLY_ADJ(DLY_ADJ),
.DLY_INCDEC(DLY_INCDEC),
.DLY_TAP_VALUE(DLY_TAP_VALUE),
.CLK_IN(CLK_IN),
.O(i_delay_out)
);

I_SERDES # (
.DATA_RATE("DDR"),
.WIDTH(WIDTH),
.DPA_MODE("NONE")
)
I_SERDES_inst (
.D(rx_dp),
.RST(RST),
.BITSLIP_ADJ(BITSLIP_ADJ),
.EN(HS_EN),
.CLK_IN(CLK_IN),
.CLK_OUT(CLK_OUT),
.Q(HS_RX_DATA),
.DATA_VALID(HS_RXD_VALID),
.DPA_LOCK(),
.DPA_ERROR(),
.PLL_LOCK(PLL_LOCK),
.PLL_CLK(RX_CLK)
);

assign RX_OE= HS_EN | LP_EN;
assign rx_dp_delay = (EN_IDLY=="FALSE")? RX_DP:i_delay_out;
assign rx_dn_delay = (EN_IDLY=="FALSE")? RX_DN:~i_delay_out;

assign rx_dp = RX_TERM_EN?1'bz:RX_OE?rx_dp_delay:'b0;
assign rx_dn = RX_TERM_EN?1'bz:RX_OE?rx_dn_delay:'b0;

assign LP_RX_DP = rx_dp;
assign LP_RX_DN = rx_dn;


always@(*)
begin
if(LP_EN && HS_EN)
$fatal(1,"\nERROR: MIPI RX instance %m LP_EN and HS_EN can't be hight at same time");
end

initial begin

if ((WIDTH < 3) || (WIDTH > 10)) begin
$fatal(1,"MIPI_RX instance %m WIDTH set to incorrect value, %d. Values must be between 3 and 10.", WIDTH);
end
case(EN_IDLY)
"TRUE" ,
"FALSE": begin end
default: begin
$fatal(1,"\nError: MIPI_RX instance %m has parameter EN_IDLY set to %s. Valid values are TRUE, FALSE\n", EN_IDLY);
end
endcase

if ((DELAY < 0) || (DELAY > 63)) begin
$fatal(1,"MIPI_RX instance %m DELAY set to incorrect value, %d. Values must be between 0 and 63.", DELAY);
end

end

endmodule
`endcelldefine
8 changes: 5 additions & 3 deletions models_internal/verilog/MIPI_TX.v
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ O_DELAY_inst (
end
end

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

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

initial begin

if ((WIDTH < 3) || (WIDTH > 10)) begin
$fatal(1,"MIPI_TX instance %m WIDTH set to incorrect value, %d. Values must be between 3 and 10.", WIDTH);
Expand Down
58 changes: 58 additions & 0 deletions models_internal/verilog/inc/MIPI_RX.inc.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@


wire i_delay_out;
wire rx_dp_delay;
wire rx_dn_delay;
wire rx_dp;
wire rx_dn;

I_DELAY # (
.DELAY(DELAY)
)
I_DELAY_inst (
.I(RX_DP),
.DLY_LOAD(DLY_LOAD),
.DLY_ADJ(DLY_ADJ),
.DLY_INCDEC(DLY_INCDEC),
.DLY_TAP_VALUE(DLY_TAP_VALUE),
.CLK_IN(CLK_IN),
.O(i_delay_out)
);

I_SERDES # (
.DATA_RATE("DDR"),
.WIDTH(WIDTH),
.DPA_MODE("NONE")
)
I_SERDES_inst (
.D(rx_dp),
.RST(RST),
.BITSLIP_ADJ(BITSLIP_ADJ),
.EN(HS_EN),
.CLK_IN(CLK_IN),
.CLK_OUT(CLK_OUT),
.Q(HS_RX_DATA),
.DATA_VALID(HS_RXD_VALID),
.DPA_LOCK(),
.DPA_ERROR(),
.PLL_LOCK(PLL_LOCK),
.PLL_CLK(RX_CLK)
);

assign RX_OE= HS_EN | LP_EN;
assign rx_dp_delay = (EN_IDLY=="FALSE")? RX_DP:i_delay_out;
assign rx_dn_delay = (EN_IDLY=="FALSE")? RX_DN:~i_delay_out;

assign rx_dp = RX_TERM_EN?1'bz:RX_OE?rx_dp_delay:'b0;
assign rx_dn = RX_TERM_EN?1'bz:RX_OE?rx_dn_delay:'b0;

assign LP_RX_DP = rx_dp;
assign LP_RX_DN = rx_dn;


always@(*)
begin
if(LP_EN && HS_EN)
$fatal(1,"\nERROR: MIPI RX instance %m LP_EN and HS_EN can't be hight at same time");
end

Empty file.
8 changes: 5 additions & 3 deletions models_internal/verilog/inc/MIPI_TX.inc.v
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ O_DELAY_inst (
end
end

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

// assign TX_DP = tx_dp;
// assign TX_DN = tx_dn;
Expand All @@ -61,4 +61,6 @@ O_DELAY_inst (
begin
if(LP_EN && HS_EN)
$fatal(1,"\nERROR: MIPI TX instance %m LP_EN and HS_EN can't be hight at same time");
end
end


167 changes: 167 additions & 0 deletions models_internal/verilog/tb/MIPI_RX_tb.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
`timescale 1ns/1ps
module MIPI_RX_tb;

// Parameters
localparam WIDTH = 4 ;
localparam EN_IDLY = "FALSE";
localparam DELAY = 0;
localparam phase = 0;

//Ports
reg RST;
reg RX_CLK;
reg PLL_LOCK;
reg CLK_IN;
reg RX_DP;
reg RX_DN;
reg HS_EN;
reg LP_EN;
reg RX_TERM_EN;
reg BITSLIP_ADJ;
reg DLY_LOAD;
reg DLY_ADJ;
reg DLY_INCDEC;
wire [5:0] DLY_TAP_VALUE;
wire [WIDTH-1:0] HS_RX_DATA;
wire HS_RXD_VALID;
wire RX_OE;
wire LP_RX_DP;
wire LP_RX_DN;

real delay;

MIPI_RX # (
.WIDTH(WIDTH),
.EN_IDLY(EN_IDLY),
.DELAY(DELAY)
)
MIPI_RX_inst (
.RST(RST),
.RX_CLK(RX_CLK),
.PLL_LOCK(PLL_LOCK),
.CLK_IN(CLK_IN),
.RX_DP(RX_DP),
.RX_DN(RX_DN),
.HS_EN(HS_EN),
.LP_EN(LP_EN),
.RX_TERM_EN(RX_TERM_EN),
.BITSLIP_ADJ(BITSLIP_ADJ),
.DLY_LOAD(DLY_LOAD),
.DLY_ADJ(DLY_ADJ),
.DLY_INCDEC(DLY_INCDEC),
.DLY_TAP_VALUE(DLY_TAP_VALUE),
.HS_RX_DATA(HS_RX_DATA),
.HS_RXD_VALID(HS_RXD_VALID),
.RX_OE(RX_OE),
.LP_RX_DP(LP_RX_DP),
.LP_RX_DN(LP_RX_DN)
);

always #0.2 RX_CLK = ! RX_CLK ; // 2.5 GHz
always #0.8 CLK_IN = ! CLK_IN ;

initial
begin
CLK_IN=0;
RX_CLK=0;
PLL_LOCK=1;
RST=0;
DLY_LOAD=0;
DLY_ADJ=0;
DLY_INCDEC=0;
RX_DP=0;
HS_EN=0;
LP_EN=0;
BITSLIP_ADJ=0;
RX_TERM_EN=0;
delay=(phase==90)?0.1:(phase==180)?0.2:(phase==270)?0.3:0;
repeat(2)@(posedge RX_CLK);
RST=1;
RX_DP=0;
HS_EN=0;
repeat(63)
begin
@(posedge RX_CLK);
#(delay);
HS_EN=1;
RX_DP=1;
@(posedge RX_CLK);
#(delay);
RX_DP=0;
@(posedge RX_CLK);
#(delay);
RX_DP=1;
@(posedge RX_CLK);
#(delay);
RX_DP=0;

end

fork
begin
repeat(20)
begin
@(posedge RX_CLK);
#(delay);
HS_EN=1;
RX_DP=1;
@(posedge RX_CLK);
#(delay);
RX_DP=0;
@(posedge RX_CLK);
#(delay);
RX_DP=1;
@(posedge RX_CLK);
#(delay);
RX_DP=0;
end
@(posedge RX_CLK);
#(delay);
RX_DP=1;
@(posedge RX_CLK);
#(delay);
RX_DP=1;
@(posedge RX_CLK);
#(delay);
RX_DP=0;
@(posedge RX_CLK);
#(delay);
RX_DP=0;

@(posedge RX_CLK);
#(delay);
RX_DP=1;
@(posedge RX_CLK);
#(delay);
RX_DP=1;
@(posedge RX_CLK);
#(delay);
RX_DP=0;
@(posedge RX_CLK);
#(delay);
RX_DP=1;
end

begin
// bitslip
repeat(3)
begin
@(negedge CLK_IN);
BITSLIP_ADJ=1;
repeat(2)@(negedge CLK_IN);
BITSLIP_ADJ=0;
end
end
join_any
#1000;
$finish;

end

assign RX_DN = ~RX_DP;
initial
begin
$dumpfile("waves.vcd");
$dumpvars;
end
endmodule
Loading

0 comments on commit 072abcc

Please sign in to comment.