Commit 4d63229c authored by Andrey Filippov's avatar Andrey Filippov

working on HiSPi simulation module

parent 9ff78344
......@@ -27,20 +27,312 @@ module par12_hispi_psp4l#(
parameter LANE1_DLY = 2.7,
parameter LANE2_DLY = 0.2,
parameter LANE3_DLY = 3.3,
parameter BLANK_LINES = 2,
parameter MAX_LINE = 8192
parameter CLK_DLY = 2.3,
parameter EMBED_LINES = 2, // number of first lines containing embedded (non-image) data
parameter MSB_FIRST = 0,
parameter FIFO_LOGDEPTH = 12 // line FIFO address bits (includes sync+latency overhead)
)(
input pclk,
input rst,
input [11:0] pxd,
input vact,
input hact,
input hact_in, // should be multiple of 4 pixels
output [3:0] lane_p,
output [3:0] lane_n,
output clk_p,
output clk_n
);
localparam FIFO_DEPTH = 1 << FIFO_LOGDEPTH;
localparam [3:0] SYNC_SOF = 3;
localparam [3:0] SYNC_SOL = 1;
localparam [3:0] SYNC_EOF = 7;
localparam [3:0] SYNC_EOL = 6;
// localparam SYNC_EMBED = 4;
integer pre_lines; // Number of lines left with "embedded" (not image) data
reg [ 1:0] lane_pcntr; // count input pixels to extend hact to 4*n if needed
wire hact = hact_in || (|lane_pcntr);
reg image_lines;
reg vact_d;
reg [47:0] pxd_d;
reg [48:0] fifo_di; // msb: 0 - data,1 sync
reg fifo_we;
reg hact_d;
reg next_sof;
reg next_line_pclk; // triggers serial output of a line (generated at SOL and EOF, wait full line)
reg next_frame_pclk; // start of a new frame on input
wire pre_fifo_we_eof_w = vact_d && !vact;
wire pre_fifo_we_sof_sol_w = vact_d && hact && !hact_d;
wire pre_fifo_we_data_w = vact_d && hact_d && (lane_pcntr == 0);
wire pre_fifo_we_w = pre_fifo_we_eof_w || pre_fifo_we_sof_sol_w || pre_fifo_we_data_w;
always @(posedge pclk) begin
vact_d <= vact;
hact_d <= hact;
pxd_d <= {pxd_d[35:0],pxd};
if (!vact) lane_pcntr <= 0;
else if (hact) lane_pcntr <= lane_pcntr + 1;
if (!vact) pre_lines <= EMBED_LINES;
else if (!image_lines && hact_d && !hact) pre_lines <= pre_lines - 1;
if (!vact) image_lines <= (EMBED_LINES != 0);
else if (!image_lines && hact_d && !hact && (pre_lines == 1)) image_lines <= 1;
if (!vact) next_sof <= 1;
else if (hact_d) next_sof <= 0;
if (!vact_d) next_line_pclk <= 1;
else next_line_pclk <= !vact || (hact && !hact_d && !next_sof);
next_frame_pclk <= vact_d && hact && !hact_d && next_sof;
fifo_we <= pre_fifo_we_w;
if (!pre_fifo_we_w) fifo_di <= 'bx;
else if (pre_fifo_we_data_w) fifo_di <= {1'b0,pxd_d};
else if (pre_fifo_we_sof_sol_w) fifo_di <= {1'b1,{4 {{ 7'b0, ~image_lines, next_sof?SYNC_SOF:SYNC_SOL}}}};
else if (pre_fifo_we_eof_w) fifo_di <= {1'b1,{4 {{7'b0, 1'b0, SYNC_EOF}}}};
end
reg [48:0] fifo_ram [0 : FIFO_DEPTH - 1];
reg [FIFO_LOGDEPTH - 1:0] fifo_wa;
always @ (posedge pclk) begin
if (rst) fifo_wa <= 0;
else if (fifo_we) fifo_wa <= fifo_wa + 1;
if (fifo_we) fifo_ram[fifo_wa] <= fifo_di;
end
// generate output clock (normally multiplier first, but in simulation there will be less calculations if division is first)
wire oclk;
wire int_clk;
wire next_line_oclk;
wire next_frame_oclk ;
reg orst_r = 1;
wire orst = rst || orst_r;
simul_clk_mult #(
.MULTIPLIER(CLOCK_MPY)
) simul_clk_mult_i (
.clk_in (pclk), // input
.en (1'b1), // input
.clk_out (int_clk) // output reg
);
sim_clk_div #(
.DIVISOR (CLOCK_DIV)
) sim_clk_div_i (
.clk_in (int_clk), // input
.en (1'b1), // input
.clk_out (oclk) // output
);
pulse_cross_clock #(
.EXTRA_DLY(0)
) pulse_cross_clock_sof_sol_i (
.rst (rst), // input
.src_clk (pclk), // input
.dst_clk (oclk), // input
.in_pulse (next_line_pclk), // input
.out_pulse (next_line_oclk), // output
.busy() // output
);
pulse_cross_clock #(
.EXTRA_DLY(0)
) pulse_cross_clock_sof_i (
.rst (rst), // input
.src_clk (pclk), // input
.dst_clk (oclk), // input
.in_pulse (next_frame_pclk), // input
.out_pulse (next_frame_oclk), // output
.busy() // output
);
always @ (oclk) begin
orst_r <= rst;
end
wire [3:0] rdy ; // all lanes operate at the same time, only one rdy bit is used
wire [3:0] sdata;
wire [3:0] sdata_dly;
reg [FIFO_LOGDEPTH - 1:0] fifo_ra;
wire [48:0] fifo_out = fifo_ram[fifo_ra];
wire fifo_dav;
// wire next_line;
wire sof_sol_sent;
reg [1:0] lines_available; // number of lines ready in FIFO
wire line_available = |lines_available;
generate
genvar i;
for (i=0; i < 4; i=i+1) begin: cmprs_channel_block
par12_hispi_psp4l_lane #(
.SYNC_SOF (SYNC_SOF),
.SYNC_SOL (SYNC_SOL),
.SYNC_EOF (SYNC_EOF),
.SYNC_EOL (SYNC_EOL),
.IDL (12'h800),
.MSB_FIRST (MSB_FIRST)
) par12_hispi_psp4l_lane_i (
.clk (oclk), // input
.rst (orst), // input
.din ({fifo_out[48], fifo_out[i * 12 +: 12]}), // input[12:0]
.dav (fifo_dav), // input
.next_line (line_available), // input
.sof_sol_sent (sof_sol_sent), // output reg
.rdy (rdy[i]), // output
.sout (sdata[i]) // output reg
);
// TODO: Add delays and diff out here?
end
endgenerate
reg [1:0] frames_open; // number of frames that are already started on input, but not yet finished on output //next_frame_oclk
wire eof_sent = rdy[0] && fifo_dav && fifo_out[48] && (fifo_out[2:0] == SYNC_EOF[2:0]);
assign fifo_dav = (|frames_open) && !(fifo_out[48] && (fifo_out[2:0] == SYNC_SOF[2:0]) && !line_available);
always @(posedge oclk) begin
if (orst) lines_available <= 0;
else if ( next_line_oclk && !sof_sol_sent) lines_available <= lines_available + 1;
else if (!next_line_oclk && sof_sol_sent) lines_available <= lines_available - 1;
if (orst) frames_open <= 0;
else if ( next_frame_oclk && !eof_sent) frames_open <= frames_open + 1;
else if (!next_frame_oclk && eof_sent) frames_open <= frames_open - 1;
if (orst) fifo_ra <= fifo_wa;
else if (fifo_dav && rdy[0]) fifo_ra <= fifo_ra + 1;
end
sim_frac_clk_delay #(
.FRAC_DELAY (LANE0_DLY),
.SKIP_FIRST (5)
) sim_frac_clk_delay0_i (
.clk (oclk), // input
.din (sdata[0]), // input
.dout (sdata_dly[0]) // output
);
sim_frac_clk_delay #(
.FRAC_DELAY (LANE1_DLY),
.SKIP_FIRST (5)
) sim_frac_clk_delay1_i (
.clk (oclk), // input
.din (sdata[1]), // input
.dout (sdata_dly[1]) // output
);
sim_frac_clk_delay #(
.FRAC_DELAY (LANE2_DLY),
.SKIP_FIRST (5)
) sim_frac_clk_delay2_i (
.clk (oclk), // input
.din (sdata[2]), // input
.dout (sdata_dly[2]) // output
);
sim_frac_clk_delay #(
.FRAC_DELAY (LANE3_DLY),
.SKIP_FIRST (5)
) sim_frac_clk_delay3_i (
.clk (oclk), // input
.din (sdata[3]), // input
.dout (sdata_dly[3]) // output
);
reg clk_pn;
wire clk_pn_dly;
always @ (posedge oclk) begin
if (orst) clk_pn <= 0;
else clk_pn <= ~clk_pn;
end
sim_frac_clk_delay #(
.FRAC_DELAY (CLK_DLY),
.SKIP_FIRST (5)
) sim_frac_clk_delay_clk_i (
.clk (oclk), // input
.din (clk_pn), // input
.dout (clk_pn_dly) // output
);
assign lane_p = sdata_dly;
assign lane_n = ~sdata_dly;
assign clk_p = clk_pn_dly;
assign clk_n = ~clk_pn_dly;
endmodule
module par12_hispi_psp4l_lane#(
parameter [3:0] SYNC_SOF = 3,
parameter [3:0] SYNC_SOL = 1,
parameter [3:0] SYNC_EOF = 7,
parameter [3:0] SYNC_EOL = 6,
parameter [11:0] IDL = 12'h800,
parameter MSB_FIRST = 0
)(
input clk,
input rst,
input [12:0] din,
input dav,
input next_line, // enable to continue seq_eol_sol
output reg sof_sol_sent, // SOL sent
output rdy,
output reg sout
);
reg [11:0] sr;
reg [11:0] sr_in;
reg sr_in_av; //
reg [ 3:0] bcntr;
reg [ 3:0] seq_sof;
reg [ 3:0] seq_eof;
reg [ 7:0] seq_eol_sol;
reg embed;
wire dav_rdy = dav && rdy;
wire is_sync = din[11];
wire [11:0] din_filt = (din[11:1] == 11'h0)? 12'h001 : din[11:0];
wire pause = seq_eol_sol[4] && !next_line;
assign rdy = !sr_in_av;
always @ (posedge clk) begin
if (rst || (bcntr == 11)) bcntr <= 0;
else bcntr <= bcntr + 1;
if (rst) sr <= 'bx;
else if (bcntr == 0) sr <= sr_in_av ? sr_in : IDL;
else sr <= MSB_FIRST ? {sr[10:0],1'b0} : {1'b0,sr[11:1]};
sout <= MSB_FIRST ? sr[11] : sr[0];
if (rst) embed <= 0;
else if (dav_rdy && is_sync) embed <= din[4];
if (rst) seq_sof <= 0;
else if (dav_rdy && is_sync && (din[3:0] == SYNC_SOF )) seq_sof <= 8;
else if (bcntr == 0) seq_sof <= seq_sof >> 1;
if (rst) seq_eof <= 0;
else if (dav_rdy && is_sync && (din[2:0] == SYNC_EOF[2:0] )) seq_eof <= 8;
else if (bcntr == 0) seq_eof <= seq_eof >> 1;
if (rst) seq_eol_sol <= 0;
else if (dav_rdy && is_sync && (din[3:0] == SYNC_SOL )) seq_eol_sol <= 80;
else if ((bcntr == 0) && !pause) seq_eol_sol <= seq_eol_sol >> 1;
if (dav_rdy) sr_in <= is_sync ? 12'hfff : din_filt;
else if ((bcntr == 0) && !pause) begin
if (seq_sof[3] || seq_eof[3] || seq_eol_sol[7] || seq_eol_sol[3]) sr_in <= 12'h0;
else if (seq_eol_sol[4]) sr_in <= 12'hfff;
else if (seq_sof[1]) sr_in <= {7'b0, embed, SYNC_SOF};
else if (seq_eof[1]) sr_in <= {7'b0, 1'b0, SYNC_EOF};
else if (seq_eol_sol[5]) sr_in <= {7'b0, 1'b0, SYNC_EOL};
else if (seq_eol_sol[1]) sr_in <= {7'b0, embed, SYNC_SOL};
end
if (rst) sr_in_av <= 0;
else if (dav_rdy) sr_in_av <= 0;
else if (bcntr == 0) sr_in_av <= (|seq_sof[3:1]) || (|seq_eof[3:1]) || ((|seq_eol_sol[7:1]) && !pause);
sof_sol_sent <= (bcntr == 0) && (seq_sof[1] || seq_eol_sol[1]);
end
endmodule
[*]
[*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI
[*] Sun Oct 11 07:47:05 2015
[*] Mon Oct 12 05:49:01 2015
[*]
[dumpfile] "/home/andrey/git/x393/simulation/x393_testbench02-20151011014314914.fst"
[dumpfile_mtime] "Sun Oct 11 07:46:34 2015"
[dumpfile_size] 4050664
[dumpfile] "/home/andrey/git/x393/simulation/x393_testbench02-20151011232311425.fst"
[dumpfile_mtime] "Mon Oct 12 05:45:31 2015"
[dumpfile_size] 86140185
[savefile] "/home/andrey/git/x393/x393_testbench02.sav"
[timestart] 16180200
[timestart] 74012100
[size] 1823 1180
[pos] 1922 0
*-15.742174 16339089 102872500 116192500 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
*-17.205360 74450000 102872500 116192500 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] x393_testbench02.
[treeopen] x393_testbench02.compressor_control.
[treeopen] x393_testbench02.par12_hispi_psp4l_i.
[treeopen] x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].
[treeopen] x393_testbench02.simul_axi_hp1_wr_i.
[treeopen] x393_testbench02.simul_axi_hp1_wr_i.waddr_i.
[treeopen] x393_testbench02.simul_clk_mult_i.
......@@ -98,7 +100,7 @@
[treeopen] x393_testbench02.x393_i.timing393_i.
[treeopen] x393_testbench02.x393_i.timing393_i.camsync393_i.
[treeopen] x393_testbench02.x393_i.timing393_i.rtc393_i.
[sst_width] 232
[sst_width] 382
[signals_width] 388
[sst_expanded] 1
[sst_vpaned_height] 611
......@@ -191,7 +193,7 @@ x393_testbench02.TEST_TITLE[639:0]
-
@1401200
-debug_ring
@c00200
@800200
-PX1
@28
x393_testbench02.simul_sensor12bits_i.MRST
......@@ -223,8 +225,125 @@ x393_testbench02.simul_sensor12bits_i.ARO
x393_testbench02.simul_sensor12bits_i.DCLK
@28
x393_testbench02.simul_sensor12bits_i.OFST
@1401200
@1000200
-PX1
@800200
-par12_hispi_sel
@28
x393_testbench02.par12_hispi_psp4l_i.rst
x393_testbench02.par12_hispi_psp4l_i.orst
x393_testbench02.par12_hispi_psp4l_i.pclk
x393_testbench02.par12_hispi_psp4l_i.oclk
@22
x393_testbench02.par12_hispi_psp4l_i.pxd[11:0]
@28
x393_testbench02.par12_hispi_psp4l_i.vact
x393_testbench02.par12_hispi_psp4l_i.hact
x393_testbench02.par12_hispi_psp4l_i.next_sof
@22
x393_testbench02.par12_hispi_psp4l_i.fifo_wa[11:0]
@28
x393_testbench02.par12_hispi_psp4l_i.fifo_we
@22
x393_testbench02.par12_hispi_psp4l_i.fifo_di[48:0]
x393_testbench02.par12_hispi_psp4l_i.fifo_ra[11:0]
x393_testbench02.par12_hispi_psp4l_i.rdy[3:0]
@200
-
@1000200
-par12_hispi_sel
@200
-
@800201
-hispi_lane0
@23
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.bcntr[3:0]
@29
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.clk
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.dav
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.dav_rdy
@23
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.din[12:0]
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.din_filt[11:0]
@29
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.embed
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.is_sync
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.next_line
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.pause
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.rdy
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.rst
@23
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.seq_eof[3:0]
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.seq_eol_sol[7:0]
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.seq_sof[3:0]
@29
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.sof_sol_sent
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.sout
@23
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.sr[11:0]
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.sr_in[11:0]
@29
x393_testbench02.par12_hispi_psp4l_i.cmprs_channel_block[0].par12_hispi_psp4l_lane_i.sr_in_av
@1000201
-hispi_lane0
@800200
-par12_hspi
@28
x393_testbench02.par12_hispi_psp4l_i.clk_n
x393_testbench02.par12_hispi_psp4l_i.clk_p
x393_testbench02.par12_hispi_psp4l_i.clk_pn
x393_testbench02.par12_hispi_psp4l_i.clk_pn_dly
x393_testbench02.par12_hispi_psp4l_i.eof_sent
x393_testbench02.par12_hispi_psp4l_i.fifo_dav
@22
x393_testbench02.par12_hispi_psp4l_i.fifo_di[48:0]
x393_testbench02.par12_hispi_psp4l_i.fifo_out[48:0]
x393_testbench02.par12_hispi_psp4l_i.fifo_ra[11:0]
x393_testbench02.par12_hispi_psp4l_i.fifo_wa[11:0]
@28
x393_testbench02.par12_hispi_psp4l_i.fifo_we
x393_testbench02.par12_hispi_psp4l_i.frames_open[1:0]
x393_testbench02.par12_hispi_psp4l_i.hact
x393_testbench02.par12_hispi_psp4l_i.hact_d
x393_testbench02.par12_hispi_psp4l_i.hact_in
x393_testbench02.par12_hispi_psp4l_i.image_lines
x393_testbench02.par12_hispi_psp4l_i.int_clk
@22
x393_testbench02.par12_hispi_psp4l_i.lane_n[3:0]
x393_testbench02.par12_hispi_psp4l_i.lane_p[3:0]
@28
x393_testbench02.par12_hispi_psp4l_i.lane_pcntr[1:0]
x393_testbench02.par12_hispi_psp4l_i.line_available
x393_testbench02.par12_hispi_psp4l_i.lines_available[1:0]
x393_testbench02.par12_hispi_psp4l_i.next_frame_oclk
x393_testbench02.par12_hispi_psp4l_i.next_frame_pclk
x393_testbench02.par12_hispi_psp4l_i.next_line_oclk
x393_testbench02.par12_hispi_psp4l_i.next_line_pclk
x393_testbench02.par12_hispi_psp4l_i.next_sof
x393_testbench02.par12_hispi_psp4l_i.oclk
x393_testbench02.par12_hispi_psp4l_i.orst
x393_testbench02.par12_hispi_psp4l_i.orst_r
x393_testbench02.par12_hispi_psp4l_i.pclk
x393_testbench02.par12_hispi_psp4l_i.pre_fifo_we_data_w
x393_testbench02.par12_hispi_psp4l_i.pre_fifo_we_eof_w
x393_testbench02.par12_hispi_psp4l_i.pre_fifo_we_sof_sol_w
x393_testbench02.par12_hispi_psp4l_i.pre_fifo_we_w
@22
x393_testbench02.par12_hispi_psp4l_i.pre_lines
x393_testbench02.par12_hispi_psp4l_i.pxd[11:0]
x393_testbench02.par12_hispi_psp4l_i.pxd_d[47:0]
x393_testbench02.par12_hispi_psp4l_i.rdy[3:0]
@28
x393_testbench02.par12_hispi_psp4l_i.rst
@22
x393_testbench02.par12_hispi_psp4l_i.sdata[3:0]
x393_testbench02.par12_hispi_psp4l_i.sdata_dly[3:0]
@28
x393_testbench02.par12_hispi_psp4l_i.sof_sol_sent
x393_testbench02.par12_hispi_psp4l_i.vact
x393_testbench02.par12_hispi_psp4l_i.vact_d
@1000200
-par12_hspi
@c00200
-PX2
@28
......
......@@ -2016,6 +2016,35 @@ simul_axi_hp_wr #(
.din(PX1_DIV_CNTR[3]), // input
.dout(TEST_DLY[1]) // output
);
wire [3:0] PX1_LANE_P;
wire [3:0] PX1_LANE_N;
wire PX1_CLK_P;
wire PX1_CLK_N;
par12_hispi_psp4l #(
.CLOCK_MPY(10),
.CLOCK_DIV(3),
.LANE0_DLY(1.3),
.LANE1_DLY(2.7),
.LANE2_DLY(0.2),
.LANE3_DLY(3.3),
.CLK_DLY(2.3),
.EMBED_LINES(2),
.MSB_FIRST(0),
.FIFO_LOGDEPTH(12)
) par12_hispi_psp4l_i (
.pclk ( PX1_MCLK), // input
.rst (!PX1_MRST), // input
.pxd (PX1_D), // input[11:0]
.vact (PX1_VACT), // input
.hact_in (PX1_HACT), // input
.lane_p (PX1_LANE_P), // output[3:0]
.lane_n (PX1_LANE_N), // output[3:0]
.clk_p (PX1_CLK_P), // output
.clk_n (PX1_CLK_N) // output
);
simul_sensor12bits #(
.lline (VIRTUAL_WIDTH), // SENSOR12BITS_LLINE),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment