Commit 1902d5ce authored by Andrey Filippov's avatar Andrey Filippov

chaneged handling of the shared parameters, added defaults and saving modified...

chaneged handling of the shared parameters, added defaults and saving modified parameters as Verilog include file
parent e6b5bfc1
......@@ -28,135 +28,115 @@
localparam LD_DLY_PHASE = DLY_LD+'h60; // 0x10e0
localparam DLY_SET = MCONTR_PHY_0BIT_ADDR + MCONTR_PHY_0BIT_DLY_SET; //0x1020
// different sets of settings for the functional simulation and the actual hardware
/*
if use200Mhz:
DLY_LANE0_DQS_WLV_IDELAY = 0xb0 # idelay dqs
DLY_LANE1_DQS_WLV_IDELAY = 0xb0 # idelay dqs
DLY_LANE0_ODELAY= [0x98,0x4c,0x94,0x94,0x98,0x9c,0x92,0x99,0x98,0x94] # odelay dqm, odelay ddqs, odelay dq[7:0]
DLY_LANE0_IDELAY= [0x40,0x13,0x14,0x14,0x1c,0x13,0x14,0x13,0x1a] # idelay dqs, idelay dq[7:0
DLY_LANE1_ODELAY= [0x98,0x4c,0x98,0x98,0x98,0x9b,0x99,0xa8,0x9c,0x98] # odelay dqm, odelay ddqs, odelay dq[7:0]
DLY_LANE1_IDELAY= [0x40,0x2c,0x2b,0x2c,0x2c,0x34,0x30,0x33,0x30] # idelay dqs, idelay dq[7:0
DLY_CMDA= [0x3c,0x3c,0x3c,0x3c,0x3b,0x3a,0x39,0x38,0x34,0x34,0x34,0x34,0x33,0x32,0x31,0x30,
0x00,0x2c,0x2c,0x2c,0x2b,0x2a,0x29,0x28,0x24,0x24,0x24,0x24,0x23,0x22,0x21,0x20] # odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
# alternative to set same type delays to the same value
DLY_DQ_IDELAY = 0x20
DLY_DQ_ODELAY = 0xa0
DLY_DQS_IDELAY = 0x40
DLY_DQS_ODELAY = 0x4c #should match with phase write leveling
DLY_DM_ODELAY = 0xa0
DLY_CMDA_ODELAY =0x50
else:
DLY_LANE0_DQS_WLV_IDELAY = 0xe8 # idelay dqs
DLY_LANE1_DQS_WLV_IDELAY = 0xe8 # idelay dqs
DLY_LANE0_ODELAY= [0x74,0x74,0x73,0x72,0x71,0x70,0x6c,0x6b,0x6a,0x69] # odelay dqm, odelay ddqs, odelay dq[7:0]
DLY_LANE0_IDELAY= [0xd8,0x73,0x72,0x71,0x70,0x6c,0x6b,0x6a,0x69] # idelay dqs, idelay dq[7:0
DLY_LANE1_ODELAY= [0x74,0x74,0x73,0x72,0x71,0x70,0x6c,0x6b,0x6a,0x69] # odelay dqm, odelay ddqs, odelay dq[7:0]
DLY_LANE1_IDELAY= [0xd8,0x73,0x72,0x71,0x70,0x6c,0x6b,0x6a,0x69] # idelay dqs, idelay dq[7:0
DLY_CMDA= [0x5c,0x5c,0x5c,0x5c,0x5b,0x5a,0x59,0x58,0x54,0x54,0x54,0x54,0x53,0x52,0x51,0x50,
0x00,0x4c,0x4c,0x4c,0x4b,0x4a,0x49,0x48,0x44,0x44,0x44,0x44,0x43,0x42,0x41,0x40] # odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
# alternative to set same type delays to the same value
DLY_DQ_IDELAY = 0x20
DLY_DQ_ODELAY = 0xa0
DLY_DQS_IDELAY = 0x40
DLY_DQS_ODELAY = 0x4c #should match with phase write leveling
DLY_DM_ODELAY = 0xa0
DLY_CMDA_ODELAY =0x50
NUM_FINE_STEPS= 5
#`endif
DLY_PHASE= 0x2c # 0x1c # mmcm fine phase shift, 1/4 tCK
*/
`ifdef TARGET_MODE
localparam T_RFC=50; // t_rfc=50 for tCK=2.5ns
localparam T_REFI=48; // t_refi; # 48/97 for normal, 8 - for simulation (7.8us <85C, 3.9us >85C)
`ifdef use200Mhz
localparam DLY_LANE0_DQS_WLV_IDELAY = 8'hb0; // idelay dqs
localparam DLY_LANE1_DQS_WLV_IDELAY = 8'hb0; // idelay dqs
localparam DLY_LANE0_ODELAY= 80'h984c9494989c92999894; // odelay dqm, odelay ddqs, odelay dq[7:0]
localparam DLY_LANE0_IDELAY= 72'h401314141c1314131a; // idelay dqs, idelay dq[7:0
localparam DLY_LANE1_ODELAY= 80'h984c9898989b99a89c98; // odelay dqm, odelay ddqs, odelay dq[7:0]
localparam DLY_LANE1_IDELAY= 72'h402c2b2c2c34303330; // idelay dqs, idelay dq[7:0
localparam DLY_CMDA= 256'h3c3c3c3c3b3a39383434343433323130002c2c2c2b2a29282424242423222120; // odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
// alternative to set same type delays to the same value
localparam DLY_DQ_IDELAY = 'h20 ;// 'h60;
localparam DLY_DQ_ODELAY = 'ha0; // 'h48;
localparam DLY_DQS_IDELAY = 'h40; // 'ha0;
localparam DLY_DQS_ODELAY = 'h4c; //
localparam DLY_DM_ODELAY = 'ha0; // 'h48;
localparam DLY_CMDA_ODELAY ='h50; // 'h30;
// localparam DLY_LANE0_ODELAY= 80'hd8a0d8d4dae0d4dcdbd9; // odelay dqm, odelay dqs, odelay dq[7:0]
// localparam DLY_LANE0_IDELAY= 72'h40989c9aa4949898a4; // idelay dqs, idelay dq[7:0]
// localparam DLY_LANE1_ODELAY= 80'hd8a0dcdcdce0dcf1e0dc; // odelay dqm, odelay dqs, odelay dq[7:0]
// localparam DLY_LANE1_IDELAY= 72'h40aca8aaa8b4acb1ac; // idelay dqs, idelay dq[7:0]
// localparam DLY_CMDA= 256'h8080808080808080808080808080808080808080808080808080808080808080; // odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
// localparam DLY_PHASE= 8'h4c; // mmcm fine phase shift, 1/4 tCK
`else
localparam DLY_LANE0_DQS_WLV_IDELAY = 8'he8; // idelay dqs
localparam DLY_LANE1_DQS_WLV_IDELAY = 8'he8; // idelay dqs
localparam DLY_LANE0_ODELAY= 80'h7474737271706c6b6a69; // odelay dqm, odelay ddqs, odelay dq[7:0]
localparam DLY_LANE0_IDELAY= 72'hd8737271706c6b6a69; // idelay dqs, idelay dq[7:0
localparam DLY_LANE1_ODELAY= 80'h7474737271706c6b6a69; // odelay dqm, odelay ddqs, odelay dq[7:0]
localparam DLY_LANE1_IDELAY= 72'hd8737271706c6b6a69; // idelay dqs, idelay dq[7:0
localparam DLY_CMDA= 256'h5c5c5c5c5b5a59585454545453525150004c4c4c4b4a49484444444443424140; // odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
// alternative to set same type delays to the same value
/* localparam DLY_DQ_IDELAY = 'h70;
localparam DLY_DQ_ODELAY = 'h68;
localparam DLY_DQS_IDELAY = 'hd8;
localparam DLY_DQS_ODELAY = 'h74; // b0 for WLV
localparam DLY_DM_ODELAY = 'h74;
localparam DLY_CMDA_ODELAY ='h50; */
localparam DLY_DQ_IDELAY = 'h20 ;// 'h60;
localparam DLY_DQ_ODELAY = 'ha0; // 'h48;
localparam DLY_DQS_IDELAY = 'h40; // 'ha0;
localparam DLY_DQS_ODELAY = 'h4c; //
localparam DLY_DM_ODELAY = 'ha0; // 'h48;
localparam DLY_CMDA_ODELAY ='h50; // 'h30;
// localparam DLY_LANE0_ODELAY= 80'h7474737271706c6b6a69; // odelay dqm, odelay ddqs, odelay dq[7:0]
// localparam DLY_LANE0_IDELAY= 72'hd8737271706c6b6a69; // idelay dqs, idelay dq[7:0
// localparam DLY_LANE1_ODELAY= 80'h7474737271706c6b6a69; // odelay dqm, odelay ddqs, odelay dq[7:0]
// localparam DLY_LANE1_IDELAY= 72'hd8737271706c6b6a69; // idelay dqs, idelay dq[7:0
// localparam DLY_CMDA= 256'h5c5c5c5c5b5a59585454545453525150004c4c4c4b4a49484444444443424140; // odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
// localparam DLY_PHASE= 8'h4c; // mmcm fine phase shift, 1/4 tCK
`endif
localparam DLY_PHASE= 8'h1c; // mmcm fine phase shift, 1/4 tCK
`else
localparam T_RFC=50; // t_rfc=50 for tCK=2.5ns
localparam T_REFI=16; // t_refi; # 48/97 for normal, 8 - for simulation (7.8us <85C, 3.9us >85C)
`ifdef use200Mhz
localparam DLY_LANE0_DQS_WLV_IDELAY = 8'hb0; // idelay dqs
localparam DLY_LANE1_DQS_WLV_IDELAY = 8'hb0; // idelay dqs
localparam DLY_LANE0_ODELAY= 80'h4c784b4a494844434241; // odelay dqm, odelay ddqs, odelay dq[7:0]
localparam DLY_LANE0_IDELAY= 72'ha0636261605c5b5a59; // idelay dqs, idelay dq[7:0
localparam DLY_LANE1_ODELAY= 80'h4c784b4a494844434241; // odelay dqm, odelay ddqs, odelay dq[7:0]
localparam DLY_LANE1_IDELAY= 72'ha0636261605c5b5a59; // idelay dqs, idelay dq[7:0
localparam DLY_CMDA= 256'h3c3c3c3c3b3a39383434343433323130002c2c2c2b2a29282424242423222120; // odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
// alternative to set same type delays to the same value
localparam DLY_DQ_IDELAY = 'h20 ;// 'h60;
localparam DLY_DQ_ODELAY = 'ha0; // 'h48;
localparam DLY_DQS_IDELAY = 'h40; // 'ha0;
localparam DLY_DQS_ODELAY = 'h78; //
localparam DLY_DM_ODELAY = 'ha0; // 'h48;
localparam DLY_CMDA_ODELAY ='h50; // 'h30;
// localparam DLY_LANE0_ODELAY= 80'h4c784b4a494844434241; // odelay dqm, odelay ddqs, odelay dq[7:0]
// localparam DLY_LANE0_IDELAY= 72'ha0636261605c5b5a59; // idelay dqs, idelay dq[7:0
// localparam DLY_LANE1_ODELAY= 80'h4c784b4a494844434241; // odelay dqm, odelay ddqs, odelay dq[7:0]
// localparam DLY_LANE1_IDELAY= 72'ha0636261605c5b5a59; // idelay dqs, idelay dq[7:0
// localparam DLY_CMDA= 256'h3c3c3c3c3b3a39383434343433323130002c2c2c2b2a29282424242423222120; // odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
// localparam DLY_PHASE= 8'h1c; // mmcm fine phase shift, 1/4 tCK
`else
localparam DLY_LANE0_DQS_WLV_IDELAY = 8'he8; // idelay dqs
localparam DLY_LANE1_DQS_WLV_IDELAY = 8'he8; // idelay dqs
localparam DLY_LANE0_ODELAY= 80'h7474737271706c6b6a69; // odelay dqm, odelay ddqs, odelay dq[7:0]
localparam DLY_LANE0_IDELAY= 72'hd8737271706c6b6a69; // idelay dqs, idelay dq[7:0
localparam DLY_LANE1_ODELAY= 80'h7474737271706c6b6a69; // odelay dqm, odelay ddqs, odelay dq[7:0]
localparam DLY_LANE1_IDELAY= 72'hd8737271706c6b6a69; // idelay dqs, idelay dq[7:0
localparam DLY_CMDA= 256'h5c5c5c5c5b5a59585454545453525150004c4c4c4b4a49484444444443424140; // odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
// alternative to set same type delays to the same value
localparam DLY_DQ_IDELAY = 'h70;
localparam DLY_DQ_ODELAY = 'h68;
localparam DLY_DQS_IDELAY = 'hd8;
localparam DLY_DQS_ODELAY = 'h74; // b0 for WLV
localparam DLY_DM_ODELAY = 'h74;
localparam DLY_CMDA_ODELAY ='h50;
// localparam DLY_LANE0_ODELAY= 80'h7474737271706c6b6a69; // odelay dqm, odelay ddqs, odelay dq[7:0]
// localparam DLY_LANE0_IDELAY= 72'hd8737271706c6b6a69; // idelay dqs, idelay dq[7:0
// localparam DLY_LANE1_ODELAY= 80'h7474737271706c6b6a69; // odelay dqm, odelay ddqs, odelay dq[7:0]
// localparam DLY_LANE1_IDELAY= 72'hd8737271706c6b6a69; // idelay dqs, idelay dq[7:0
// localparam DLY_CMDA= 256'h5c5c5c5c5b5a59585454545453525150004c4c4c4b4a49484444444443424140; // odelay odt, cke, cas, ras, we, ba2,ba1,ba0, X, a14,..,a0
// localparam DLY_PHASE= 8'h1c; // mmcm fine phase shift, 1/4 tCK
`endif
localparam DLY_PHASE= 8'h1c; // mmcm fine phase shift, 1/4 tCK
`endif
// alternative to set same type delays to the same value
localparam DLY_DQ_IDELAY = ( (DLY_LANE0_IDELAY & 8'hff)+
((DLY_LANE0_IDELAY>> 8) & 8'hff)+
((DLY_LANE0_IDELAY>>16) & 8'hff)+
((DLY_LANE0_IDELAY>>24) & 8'hff)+
((DLY_LANE0_IDELAY>>32) & 8'hff)+
((DLY_LANE0_IDELAY>>40) & 8'hff)+
((DLY_LANE0_IDELAY>>48) & 8'hff)+
((DLY_LANE0_IDELAY>>56) & 8'hff)+
(DLY_LANE1_IDELAY & 8'hff)+
((DLY_LANE1_IDELAY>> 8) & 8'hff)+
((DLY_LANE1_IDELAY>>16) & 8'hff)+
((DLY_LANE1_IDELAY>>24) & 8'hff)+
((DLY_LANE1_IDELAY>>32) & 8'hff)+
((DLY_LANE1_IDELAY>>40) & 8'hff)+
((DLY_LANE1_IDELAY>>48) & 8'hff)+
((DLY_LANE1_IDELAY>>56) & 8'hff)+ 8 ) >> 4;
localparam DLY_DQ_ODELAY = (((DLY_LANE0_ODELAY & 8'hff)+
((DLY_LANE0_ODELAY>> 8) & 8'hff)+
((DLY_LANE0_ODELAY>>16) & 8'hff)+
((DLY_LANE0_ODELAY>>24) & 8'hff)+
((DLY_LANE0_ODELAY>>32) & 8'hff)+
((DLY_LANE0_ODELAY>>40) & 8'hff)+
((DLY_LANE0_ODELAY>>48) & 8'hff)+
((DLY_LANE0_ODELAY>>56) & 8'hff)+
(DLY_LANE1_ODELAY & 8'hff)+
((DLY_LANE1_ODELAY>> 8) & 8'hff)+
((DLY_LANE1_ODELAY>>16) & 8'hff)+
((DLY_LANE1_ODELAY>>24) & 8'hff)+
((DLY_LANE1_ODELAY>>32) & 8'hff)+
((DLY_LANE1_ODELAY>>40) & 8'hff)+
((DLY_LANE1_ODELAY>>48) & 8'hff)+
((DLY_LANE1_ODELAY>>56) & 8'hff)+ 8 ) >> 4);
localparam DLY_DQS_IDELAY = (((DLY_LANE0_IDELAY>>64) & 8'hff)+
((DLY_LANE1_IDELAY>>64) & 8'hff)+ 1 ) >> 1;
localparam DLY_DQS_ODELAY = (((DLY_LANE0_ODELAY>>64) & 8'hff)+
((DLY_LANE1_ODELAY>>64) & 8'hff)+ 1 ) >> 1;
localparam DLY_DM_ODELAY = DLY_DQ_ODELAY;
localparam DLY_CMDA_ODELAY =(((DLY_CMDA>> 0) & 8'hff)+
((DLY_CMDA>> 8) & 8'hff)+
((DLY_CMDA>>'h10) & 8'hff)+
((DLY_CMDA>>'h18) & 8'hff)+
((DLY_CMDA>>'h20) & 8'hff)+
((DLY_CMDA>>'h28) & 8'hff)+
((DLY_CMDA>>'h30) & 8'hff)+
((DLY_CMDA>>'h38) & 8'hff)+
((DLY_CMDA>>'h40) & 8'hff)+
((DLY_CMDA>>'h48) & 8'hff)+
((DLY_CMDA>>'h50) & 8'hff)+
((DLY_CMDA>>'h58) & 8'hff)+
((DLY_CMDA>>'h60) & 8'hff)+
((DLY_CMDA>>'h68) & 8'hff)+
((DLY_CMDA>>'h70) & 8'hff)+
((DLY_CMDA>>'hc0) & 8'hff)+
((DLY_CMDA>>'hc8) & 8'hff)+
((DLY_CMDA>>'hd0) & 8'hff)+
((DLY_CMDA>>'hd8) & 8'hff)+
((DLY_CMDA>>'he0) & 8'hff)+
((DLY_CMDA>>'he8) & 8'hff)+
((DLY_CMDA>>'hf0) & 8'hff)+
((DLY_CMDA>>'hf8) & 8'hff)+ 12 ) / 23;
localparam DLY_LANE0_DQS_WLV_IDELAY = DLY_DQS_IDELAY; // b0; // idelay dqs
localparam DLY_LANE1_DQS_WLV_IDELAY = DLY_DQS_IDELAY; // b0; idelay dqs
localparam DQSTRI_FIRST= 4'h3; // DQS tri-state control word, first when enabling output
localparam DQSTRI_LAST= 4'hc; // DQS tri-state control word, first after disabling output
localparam DQTRI_FIRST= 4'h7; // DQ tri-state control word, first when enabling output
localparam DQTRI_LAST= 4'he; // DQ tri-state control word, first after disabling output
localparam WBUF_DLY_DFLT= DFLT_WBUF_DELAY; //4'h8; // 4'h6; // extra delay (in mclk cycles) to add to write buffer enable (DDR3 read data)
localparam WBUF_DLY_WLV= 4'h7; // write leveling mode: extra delay (in mclk cycles) to add to write buffer enable (DDR3 read data)
localparam WBUF_DLY_DFLT= DFLT_WBUF_DELAY; // 4'h8; // 4'h6; // extra delay (in mclk cycles) to add to write buffer enable (DDR3 read data)
localparam WBUF_DLY_WLV= DFLT_WBUF_DELAY; // 4'h7; // write leveling mode: extra delay (in mclk cycles) to add to write buffer enable (DDR3 read data)
// localparam DLY_PHASE= 8'hdb; // mmcm fine phase shift
localparam INITIALIZE_OFFSET= 'h00; // moemory initialization start address (in words) ..`h0c
......@@ -172,3 +152,34 @@ DLY_PHASE= 0x2c # 0x1c # mmcm fine phase shift, 1/4 tCK
localparam STATUS_MSB_RSHFT= 2; // status bits [25:2] are read through [23:0]
localparam STATUS_PSHIFTER_RDY_MASK = 1<<STATUS_2LSB_SHFT;
localparam FRAME_START_ADDRESS= 'h1000; // RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
localparam FRAME_FULL_WIDTH= 'h0c0; // Padded line length (8-row increment), in 8-bursts (16 bytes)
// localparam SCANLINE_WINDOW_WH= `h079000a2; // 2592*1936: low word - 13-bit window width (0->'h4000), high word - 16-bit frame height (0->'h10000)
// localparam SCANLINE_WINDOW_WH= 'h0009000b; // 176*9: low word - 13-bit window width (0->'h4000), high word - 16-bit frame height (0->'h10000)
localparam WINDOW_WIDTH= 'h000b; //'h005b; //'h000b; // 176: 13-bit window width (0->'h4000)
localparam WINDOW_HEIGHT= 'h000a; // 9: 16-bit window height (0->'h10000)
// localparam SCANLINE_X0Y0= 'h00050003; // X0=3*16=48, Y0=5: // low word - 13-bit window left, high word - 16-bit window top
localparam WINDOW_X0= 'h5c; //'h7f; // 'h005c; // 'h7c; // 'h0003; // X0=3*16=48 - 13-bit window left
localparam WINDOW_Y0= 'h0005; // Y0=5: 16-bit window top
// localparam SCANLINE_STARTXY= 'h0; // low word - 13-bit start X (relative to window), high word - 16-bit start y (normally 0)
localparam SCANLINE_STARTX= 'h0; // 13-bit start X (relative to window), high word (normally 0)
localparam SCANLINE_STARTY= 'h0; // 16-bit start y (normally 0)
localparam [1:0] SCANLINE_EXTRA_PAGES= 0; // 0..2 - number of pages in the buffer to keep/not write // SuppressThisWarning VEditor - not used
localparam TILED_STARTX= 'h0; // 13-bit start X (relative to window), high word (normally 0)
localparam TILED_STARTY= 'h0; // 16-bit start y (normally 0)
localparam [1:0] TILED_EXTRA_PAGES= 0; // 0..2 - number of pages in the buffer to keep/not write
localparam TILED_KEEP_OPEN= 1'b1; //1'b1; // 1'b0; // Do not close banks between reads (valid only for tiles <=8 rows, needed if less than 3? rows)
localparam TILE_WIDTH= 'h04; // 6-bit tile width (1..'h40)
localparam TILE_HEIGHT= 'h08; //'h05; // 'h04; //'h06; // 6-bit tile height (1..'h40) // 4 - violation
localparam TILE_VSTEP= 'h04; // 6-bit tile vertical step, with no overlap it is equal to TILE_HEIGHT (1..'h40)
localparam TEST01_START_FRAME= 1;
localparam TEST01_NEXT_PAGE= 2;
localparam TEST01_SUSPEND= 4; // SuppressThisWarning VEditor - not used
localparam TEST_INITIAL_BURST= 4; // 3;
\ No newline at end of file
......@@ -105,13 +105,13 @@
parameter CHNBUF_READ_LATENCY = 2, //1, // external channel buffer extra read latency ( 0 - data available next cycle after re (but prev. data))
parameter DFLT_DQS_PATTERN= 8'h55,
parameter DFLT_DQS_PATTERN= 8'haa, // TODO: make work for the simulator too 8'h55,
parameter DFLT_DQM_PATTERN= 8'h00, // 8'h00
parameter DFLT_DQ_TRI_ON_PATTERN= 4'h7, // DQ tri-state control word, first when enabling output
parameter DFLT_DQ_TRI_OFF_PATTERN= 4'he, // DQ tri-state control word, first after disabling output
parameter DFLT_DQS_TRI_ON_PATTERN= 4'h3, // DQS tri-state control word, first when enabling output
parameter DFLT_DQS_TRI_OFF_PATTERN=4'hc, // DQS tri-state control word, first after disabling output
parameter DFLT_WBUF_DELAY= 4'h8, // write levelling - 7!
parameter DFLT_WBUF_DELAY= 4'h9, // TODO: Find the reason - simulation needs 8, target - 9
parameter DFLT_INV_CLK_DIV= 1'b0,
parameter DFLT_CHN_EN= 16'h0, // channel mask to be enabled at reset
......
-v
-d TARGET_MODE=1
-f ../system_defines.vh
-f ../includes/x393_parameters.vh ../includes/x393_localparams.vh
-f ../includes/x393_parameters.vh ../includes/x393_cur_params_target.vh ../includes/x393_localparams.vh
-l ../includes/x393_cur_params_target_gen.vh
-p NEWPAR='h3ff
-c write_mem 0x377 25
-c read_mem 0x3ff
......
-d TARGET_MODE=1
-f /usr/local/verilog/system_defines.vh
-f /usr/local/verilog/x393_parameters.vh /usr/local/verilog/x393_localparams.vh
-f /usr/local/verilog/x393_parameters.vh /usr/local/verilog/x393_cur_params_target.vh /usr/local/verilog/x393_localparams.vh
-l /usr/local/verilog/x393_cur_params_target.vh
-p NEWPAR='h3ff
-i
\ No newline at end of file
......@@ -31,17 +31,22 @@ import re
import os
import string
from verilog_utils import getParWidth
#import vrlg
"""
class VerilogParameters(object): #this is Borg
__shared_state = {}
def __init__(self, parameters=None):
self.__dict__ = self.__shared_state
if (parameters):
vrlg.init_vars(self.parsToDict(parameters))
def parsToDict(self, parameters=None):
adict={}
for parName in parameters:
adict[parName]= parameters[parName][0]
adict[parName+"__TYPE"]=parameters[parName][1]
adict[parName+"__RAW"]= parameters[parName][2]
self.__dict__.update(adict)
return adict
"""
class ImportVerilogParameters(object):
'''
......@@ -67,6 +72,13 @@ class ImportVerilogParameters(object):
self.defines=defines.copy()
if rootPath:
self.rootPath=rootPath.rstrip(os.sep)
def parsToDict(self, parameters=None):
adict={}
for parName in parameters:
adict[parName]= parameters[parName][0]
adict[parName+"__TYPE"]=parameters[parName][1]
adict[parName+"__RAW"]= parameters[parName][2]
return adict
'''
http://stackoverflow.com/questions/241327/python-snippet-to-remove-c-and-c-comments
'''
......@@ -338,23 +350,19 @@ class ImportVerilogParameters(object):
pass
def parsePrimary(start=0):
return useBest(useBest(useBest(parseString(start),parseNumber(start)),parseRealNumber(start)),parseParameter(start))
def parsePrimaryOrBinary(start=0):
operand1=parsePrimary(start)
if (self.verbose>2) and (start !=0):
print ("parsePrimaryOrBinary(start=%d), line=%s, result=%s"%(start,line,str(operand1)))
if not operand1: print (line)
opStart=skipWS(operand1[2])
if opStart == len(line): # just primary
return operand1
# Try binary operation
def parseBinary(operand1, opStart):
op=getBinOp(opStart)
if not op:
print("ERROR: Next token in '%s' (starting from %s) is not a binary operation"%(line,line[opStart:]))
return None
return None # not a binary operation
# if "( (DLY_LANE0_IDELAY & 8'hff)" in line:
# print("parseBinary(): %d(%d): %s"%(opStart,len(line),line[opStart:]))
# if (opStart>530):
# print ("(pre)Last one!")
start2=skipWS(opStart+len(op[0]))
if (self.verbose>2):
print ("line=%s"%line)
print ("start=%d, opStart=%d, start2=%d"%(start,opStart, start2))
print ("opStart=%d, start2=%d"%(opStart, start2))
operand2=parseExp(start2)
if not operand2:
print("ERROR: Could not get the second operand for '%s' in '%s'"%(op[0],line))
......@@ -376,39 +384,91 @@ class ImportVerilogParameters(object):
width=32
return (exp[0],"[%d:0]"%(width-1),operand2[2])
def parseExp(start=0):
def parsePrimaryOrBinary(start=0):
operand1=parsePrimary(start)
if (self.verbose>2) and (start !=0):
print ("parsePrimaryOrBinary(start=%d), line=%s, result=%s"%(start,line,str(operand1)))
if not operand1: print (line)
# Try binary operation
# repeat until end of line or ')'
while True:
opStart=skipWS(operand1[2])
if (opStart == len(line)) : # or (line[opStart] == ')'): # just primary
return operand1
if line[opStart] == ')': # just primary
return operand1
binRes=parseBinary(operand1, opStart)
if not binRes:
print ("opStart=%d, len(line)=%d, operand1=%s"%(opStart,len(line),str(operand1)))
print()
print(line)
raise Exception("ERROR: Next token in '%s' (starting from '%s') is not a binary operation"%
(line,line[opStart:]))
operand1=binRes
def parseExp(start=0, topExpr=False):
start=skipWS(start)
if start>=len(line):
print ("ERROR: EOL reached when expression was expected in '%s'"%line)
return None
if line[start]=='(':
exp=parseExp(start+1)
# if "( (DLY_LANE0_IDELAY & 8'hff)" in line:
# print (line)
# if (line[0]=='(') and (start==0):
# print("Line starts with '(")
if (line[start]=='(') or topExpr:
# if (line[start]=='('):
if not topExpr:
start+=1
exp=parseExp(start)
if not exp:
print ("ERROR: failed to evaluate expression in '%s' (starting from '%s'"%(line,line[start:]))
return None
while True:
endPos=skipWS(exp[2])
if endPos >= len(line):
if (endPos >= len(line)) and (not topExpr):
print ("ERROR: EOL reached when closing ')' was expected in '%s'"%line)
return None
if line[endPos] != ")":
print ("ERROR: Found '%s'when closing ')' was expected in '%s'"%(line[endPos],line))
return None
if (endPos >= len(line)) or (line[endPos] == ")"): # (endPos >= len(line)) can only be here if topExpr
endPos=skipWS(endPos+1)
return (exp[0],"[%d:0]"%(exp[1]-1),endPos)
if (exp is None) or (exp[1] is None):
print ("line=%s"%(line))
print ()
# print ("exp=%s"%(str(exp)))
if isinstance(exp[0],(int,long)):
width=getParWidth(exp[1])
elif isinstance(exp[0],str):
width=8*len(exp[0])
else:
# width=0
# print ("Unrecognized width in %s"%(str(exp)))
# print ("line=%s"%(line))
return (exp[0],exp[1],endPos)
return (exp[0],"[%d:0]"%(width-1),endPos)
# here may be binOp
binRes=parseBinary(exp, endPos)
if not binRes:
print ("endPos=%d, len(line)=%d, exp=%s"%(endPos,len(line),str(exp)))
raise Exception("ERROR: Next token in '%s' (starting from '%s') is not a binary operation or closing')'"%
(line,line[endPos:]))
exp=binRes
return parsePrimaryOrBinary(start)
'''
parseExpression top level code
no support for bit select, &&, ||, ~ ! ? and more...
'''
return parseExp(0)
return parseExp(0,True) # call top level expression that does not need enclosing ()
'''
Read parameters defined in parameter port list (inside #(,,,), comma separated (last may have no comma)
Adds parsed parameters to the dictionary
'''
def readParameterPortList(self,path,portMode=True):
if (self.verbose>2):
print ("readParameterPortList:Processing %s"%(path))
if (self.verbose>0):
print ("readParameterPortList:Processing %s"%(os.path.abspath(path)))
with open (path, "r") as myfile: #with will close file when done
text=myfile.read()
# remove /* */ comments
......
......@@ -22,6 +22,7 @@
@contact: andrey@elphel.coml
@deffield updated: Updated
'''
from __builtin__ import str
__author__ = "Andrey Filippov"
__copyright__ = "Copyright 2015, Elphel, Inc."
__license__ = "GPL"
......@@ -43,7 +44,7 @@ from argparse import ArgumentParser
from argparse import RawDescriptionHelpFormatter
from import_verilog_parameters import ImportVerilogParameters
from import_verilog_parameters import VerilogParameters
#from import_verilog_parameters import VerilogParameters
from verilog_utils import hx
import x393_mem
......@@ -54,6 +55,7 @@ import x393_mcntrl_timing
import x393_mcntrl_buffers
import x393_mcntrl_tests
import x393_mcntrl_adjust
import vrlg
__all__ = []
__version__ = 0.1
__date__ = '2015-03-01'
......@@ -90,7 +92,17 @@ def extractTasks(obj,inst):
# print ("COMMENTS:"+str(inspect.getcomments(obj.__dict__[name])))
# print ("DOCS:"+str(inspect.getdoc(obj.__dict__[name])))
func_args=obj.__dict__[name].func_code.co_varnames[1:obj.__dict__[name].func_code.co_argcount]
callableTasks[name]={'func':obj.__dict__[name],'args':func_args,'inst':inst,'docs':inspect.getdoc(obj.__dict__[name])}
# print("%s: %d, varnames=%s func_args=%s, defaults=%s"%
# (name,
# obj.__dict__[name].func_code.co_argcount,
# str(obj.__dict__[name].func_code.co_varnames),
# str(func_args),
# obj.__dict__[name].func_defaults))
callableTasks[name]={'func':obj.__dict__[name],
'args':func_args,
'dflts':obj.__dict__[name].func_defaults,
'inst':inst,
'docs':inspect.getdoc(obj.__dict__[name])}
def execTask(commandLine):
result=None
cmdList=commandLine #.split()
......@@ -128,14 +140,22 @@ def execTask(commandLine):
def getFuncArgsString(name):
funcFArgs=callableTasks[name]['args']
funcFArgs=callableTasks[name]['args'] # () if none
funcDflts=callableTasks[name]['dflts'] # None if no parameters, not empty tuple
# print ("<<< %s : %s"%(funcFArgs,funcDflts))
sFuncArgs=""
if funcFArgs:
sFuncArgs+='<'+str(funcFArgs[0])+'>'
for a in funcFArgs[1:]:
sFuncArgs+=' <'+str(a)+'>'
offs=len(funcFArgs)
if not funcDflts is None:
offs-=len(funcDflts)
# sFuncArgs+='<'+str(funcFArgs[0])+'>'
for i,a in enumerate(funcFArgs):
sFuncArgs+=' <'+str(a)
if i>=offs:
sFuncArgs+='='+str(funcDflts[i-offs])
sFuncArgs+='> '
return sFuncArgs
#dflts
def main(argv=None): # IGNORE:C0111
'''Command line options.'''
......@@ -168,9 +188,6 @@ def main(argv=None): # IGNORE:C0111
USAGE
''' % (program_shortdesc, __author__,str(__date__))
preDefines={}
preParameters={}
showResult=False
try:
# Setup argument parser
parser = ArgumentParser(description=program_license, formatter_class=RawDescriptionHelpFormatter,fromfile_prefix_chars='@')
......@@ -185,12 +202,15 @@ USAGE
parser.add_argument("-i", "--interactive", dest="interactive", action="store_true", help="enter interactive mode [default: %(default)s]")
parser.add_argument("-s", "--simulated", dest="simulated", action="store_true", help="Simulated mode (no real hardware I/O) [default: %(default)s]")
parser.add_argument("-x", "--exceptions", dest="exceptions", action="count", help="Exit on more exceptions [default: %(default)s]")
parser.add_argument("-l", "--localparams", dest="localparams", action="store", default="",
help="path were modified parameters are saved [default: %(default)s]", metavar="path")
# Process arguments
args = parser.parse_args()
if not args.exceptions:
args.exceptions=0
QUIET = (1,0)[args.exceptions]
# print ("args.exception=%d, QUIET=%d"%(args.exceptions,QUIET))
if not args.simulated:
......@@ -208,7 +228,13 @@ USAGE
for group in args.paths:
for item in group:
paths+=item.split()
#print("+++ paths=%s"% str(paths))
print("+++ paths=%s"% str(paths))
print("localparams=%s"%str(args.localparams))
preDefines={}
preParameters={}
showResult=False
if (args.defines):
defines=[]
for group in args.defines:
......@@ -235,7 +261,6 @@ USAGE
if len(kv)>1:
preParameters[kv[0]]=(kv[1],"RAW",kv[1])
#print("+++ parameters=%s"% str(preParameters))
commands=[]
if (args.commands):
for group in args.commands:
......@@ -244,9 +269,6 @@ USAGE
cmd+=item.split()
commands.append(cmd)
#print("+++ commands=%s"% str(commands))
except KeyboardInterrupt:
### handle keyboard interrupt ###
return 0
......@@ -268,7 +290,11 @@ USAGE
### do something with inpath ###
ivp.readParameterPortList(path)
parameters=ivp.getParameters()
vpars=VerilogParameters(parameters)
#set all verilog parameters as module-level ones in vrlg (each parameter creates 3 names)
if (parameters):
vrlg.init_vars(ivp.parsToDict(parameters))
# vpars=VerilogParameters(parameters)
if verbose > 3:
defines= ivp.getDefines()
print ("======= Extracted defines =======")
......@@ -280,18 +306,13 @@ USAGE
print (par+" = "+hex(parameters[par][0])+" (type = "+parameters[par][1]+" raw = "+parameters[par][2]+")")
except:
print (par+" = "+str(parameters[par][0])+" (type = "+parameters[par][1]+" raw = "+parameters[par][2]+")")
print("vpars.VERBOSE="+str(vpars.VERBOSE))
print("vpars.VERBOSE__TYPE="+str(vpars.VERBOSE__TYPE))
print("vpars.VERBOSE__RAW="+str(vpars.VERBOSE__RAW))
print("vrlg.VERBOSE="+str(vrlg.VERBOSE))
print("vrlg.VERBOSE__TYPE="+str(vrlg.VERBOSE__TYPE))
print("vrlg.VERBOSE__RAW="+str(vrlg.VERBOSE__RAW))
if verbose > 3: print (VerilogParameters.__dict__)
vpars1=VerilogParameters()
if verbose > 3: print("vpars1.VERBOSE="+str(vpars1.VERBOSE))
if verbose > 3: print("vpars1.VERBOSE__TYPE="+str(vpars1.VERBOSE__TYPE))
if verbose > 3: print("vpars1.VERBOSE__RAW="+str(vpars1.VERBOSE__RAW))
x393mem= x393_mem.X393Mem(verbose,args.simulated) #add dry run parameter
x393utils= x393_utils.X393Utils(verbose,args.simulated)
x393utils= x393_utils.X393Utils(verbose,args.simulated,args.localparams)
x393tasks= x393_axi_control_status.X393AxiControlStatus(verbose,args.simulated)
x393Pio= x393_pio_sequences.X393PIOSequences(verbose,args.simulated)
x393Timing= x393_mcntrl_timing.X393McntrlTiming(verbose,args.simulated)
......@@ -322,27 +343,6 @@ USAGE
extractTasks(x393_mcntrl_tests.X393McntrlTests,x393Tests)
extractTasks(x393_mcntrl_adjust.X393McntrlAdjust,x393Adjust)
#
"""
if verbose > 3:
funcName="read_mem"
funcArgs=[0x377,123]
print ('==== testing function : '+funcName+str(funcArgs)+' ====')
# execTask(commandLine)
try:
callableTasks[funcName]['func'](callableTasks[funcName]['inst'],*funcArgs)
except Exception as e:
print ('Error while executing %s'%funcName)
funcFArgs= callableTasks[funcName]['args']
sFuncArgs=""
if funcFArgs:
sFuncArgs+='<'+str(funcFArgs[0])+'>'
for a in funcFArgs[1:]:
sFuncArgs+=' <'+str(a)+'>'
print ("Usage:\n%s %s"%(funcName,sFuncArgs))
print ("exception message:"+str(e))
"""
for cmdLine in commands:
print ('Running task: '+str(cmdLine))
rslt= execTask(cmdLine)
......@@ -370,6 +370,7 @@ USAGE
print ('\n"parameters" and "defines" list known defined parameters and macros')
print ("args.exception=%d, QUIET=%d"%(args.exceptions,QUIET))
print ("Enter 'R' to toggle show/hide command results, now it is %s"%(("OFF","ON")[showResult]))
print ("Use 'pydev_predefines' to generate a parameter list to paste to vrlg.py, so Pydev will be happy")
elif lineList[0].upper() == 'R':
if len(lineList)>1:
if (lineList[1].upper() == "ON") or (lineList[1].upper() == "1") or (lineList[1].upper() == "TRUE"):
......@@ -443,8 +444,53 @@ USAGE
print ("`"+macro+": "+str(val))
if nameFilter is None:
print(" 'defines' command accepts regular expression as a second parameter to filter the list")
elif (lineList[0] == 'pydev_predefines'):
predefines=""
for k,v in ivp.parsToDict(parameters).items():
typ=str(type(v))
typ=typ[typ.find("'")+1:typ.rfind("'")]
if "None" in typ:
typ="None"
predefines += "%s = %s\n"%(k,typ)
# print ("%s = %s"%(k,typ))
vrlg_path=vrlg.__dict__["init_vars"].func_code.co_filename
# print ("vrlg path: %s"%(vrlg_path))
try:
magic="#### PyDev predefines"
with open (vrlg_path, "r") as vrlg_file:
vrlg_text=vrlg_file.read()
index= vrlg_text.index(magic) #will fail if not found
index= vrlg_text.index('\n',index)
vrlg_text=vrlg_text[:index+1]+"\n"+predefines
except:
print ("Failed to update %s - it is either missing or does not have a '%s'"%(vrlg_path,magic))
continue
try:
with open (vrlg_path, "w") as vrlg_file:
vrlg_file.write(vrlg_text)
print ("Updated file %s"%(vrlg_path))
except:
print ("Failed to re-write %s\n"%(vrlg_path))
print (vrlg_text)
print ("\nFailed to re-write %s"%(vrlg_path))
else:
cmdLine=line.split()
# cmdLine=line.split()
cmdLine=[lineList[0]]
l=line[len(lineList[0]):].strip()
while l:
if l[0] == '"':
indx=l.find('"',1) # skip opening
if indx > 0:
cmdLine.append(l[:indx+1]) # including ""
l=l[indx+1:].strip()
continue
indx=l.find(' ')
if indx<0:
indx=len(l) # use all the remaining l as next argument
cmdLine.append(l[:indx]) # including ""
l=l[indx:].strip()
# strarg=line[len(lineList[0]):].strip()
rslt= execTask(cmdLine)
if showResult:
print (' Result: '+hx(rslt))
......
......@@ -56,7 +56,7 @@ def concat(items):
width=0
for vw in reversed(items):
v=vw[0]
if not isinstance(v,int):
if not isinstance(v,(int,long)):
if v:
v=1 # So True/False will also work, not just 0/1
else:
......@@ -150,7 +150,7 @@ def checkIntArgs(names,var_dict):
v=var_dict[name]
except:
raise Exception("ERROR: '%s' is not among %s"%(name,str(var_dict.keys())))
if not isinstance(v,int):
if not isinstance(v,(int,long)):
print ("Expected an integer for '%s', got '%s"%(name,v))
try:
d=int(v,16)
......
......@@ -30,11 +30,12 @@ __email__ = "andrey@elphel.com"
__status__ = "Development"
#import sys
#import x393_mem
from import_verilog_parameters import VerilogParameters
#from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem
#from verilog_utils import hx,concat, bits
from verilog_utils import hx
from time import time
import vrlg
class X393AxiControlStatus(object):
DRY_MODE= True # True
DEBUG_MODE=1
......@@ -46,20 +47,8 @@ class X393AxiControlStatus(object):
def __init__(self, debug_mode=1,dry_mode=True):
self.DEBUG_MODE=debug_mode
self.DRY_MODE=dry_mode
# self.vpars=VerilogParameters()
self.x393_mem=X393Mem(debug_mode,dry_mode)
# print ("+++++++++++++++ self.__dict__ ++++++++++++++++++++++++++")
# print (self.__dict__)
# print ("+++++++++++++++ VerilogParameters.__dict__ ++++++++++++++++++++++++++")
# print (VerilogParameters.__dict__)
# self.__dict__.update(VerilogParameters.__dict__) # Add verilog parameters to the class namespace
self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
# try:
# verbose=self.verbose
# except:
# pass
# print ("+++++++++++++++ self.__dict__ ++++++++++++++++++++++++++")
# print (self.__dict__)
# self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
'''
Maybe import parameters into the module, not class namespace to use directly, w/o self. ?
# __dict__.update(VerilogParameters.__dict__) # Add verilog parameters to the class namespace
......@@ -71,7 +60,7 @@ class X393AxiControlStatus(object):
<addr> - register address relative to the control register address space
<data> - 32-bit data to write
"""
self.x393_mem.axi_write_single_w(self.CONTROL_ADDR+reg_addr, data)
self.x393_mem.axi_write_single_w(vrlg.CONTROL_ADDR+reg_addr, data)
def test_read_status(self, rpt): # was read_and_wait_status
"""
Read word from the status register 0 and calculate part of the run busy
......@@ -79,7 +68,7 @@ class X393AxiControlStatus(object):
"""
num_busy=0
for _ in range(rpt):
num_busy+=(self.x393_mem.axi_read_addr_w(self.STATUS_ADDR + 0)>>8) & 1
num_busy+=(self.x393_mem.axi_read_addr_w(vrlg.STATUS_ADDR + 0)>>8) & 1
ratio=(1.0* num_busy)/rpt
print (("num_busy=%d, rpt=%d, ratio=%f"%(num_busy,rpt,100*ratio))+"%")
return ratio
......@@ -88,7 +77,7 @@ class X393AxiControlStatus(object):
Read word from the status register (up to 26 bits payload and 6-bit sequence number)
<addr> - status register address (currently 0..255)
"""
return self.x393_mem.axi_read_addr_w(self.STATUS_ADDR + address )
return self.x393_mem.axi_read_addr_w(vrlg.STATUS_ADDR + address )
def wait_status_condition(self,
status_address, # input [STATUS_DEPTH-1:0] status_address;
status_control_address, # input [29:0] status_control_address;
......@@ -121,10 +110,10 @@ class X393AxiControlStatus(object):
while not match:
data=self.read_status(status_address)
if wait_seq:
seq_num = ((data >> self.STATUS_SEQ_SHFT) ^ 0x20) & 0x30
seq_num = ((data >> vrlg.STATUS_SEQ_SHFT) ^ 0x20) & 0x30
self.write_contol_register(status_control_address, ((status_mode & 3) <<6) | (seq_num & 0x3f))
data=self.read_status(status_address)
while (((data >> self.STATUS_SEQ_SHFT) ^ seq_num) & 0x30) !=0:
while (((data >> vrlg.STATUS_SEQ_SHFT) ^ seq_num) & 0x30) !=0:
data=self.read_status(status_address)
if self.DRY_MODE: break
if timeout and (time()>endTime):
......@@ -151,17 +140,17 @@ class X393AxiControlStatus(object):
# for name in self.__dict__:
# print (name+": "+str(name=='MCONTR_PHY_STATUS_REG_ADDR'))
# print (self.__dict__['MCONTR_PHY_STATUS_REG_ADDR'])
print ("MCONTR_PHY_STATUS_REG_ADDR: %s"%(hx(self.read_status(self.MCONTR_PHY_STATUS_REG_ADDR),8)))
print ("MCONTR_TOP_STATUS_REG_ADDR: %s"%(hx(self.read_status(self.MCONTR_TOP_STATUS_REG_ADDR),8)))
print ("MCNTRL_PS_STATUS_REG_ADDR: %s"%(hx(self.read_status(self.MCNTRL_PS_STATUS_REG_ADDR) ,8)))
print ("MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR:%s"%(hx(self.read_status(self.MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR),8)))
print ("MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR:%s"%(hx(self.read_status(self.MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR),8)))
print ("MCNTRL_TILED_STATUS_REG_CHN2_ADDR: %s"%(hx(self.read_status(self.MCNTRL_TILED_STATUS_REG_CHN2_ADDR),8)))
print ("MCNTRL_TILED_STATUS_REG_CHN4_ADDR: %s"%(hx(self.read_status(self.MCNTRL_TILED_STATUS_REG_CHN4_ADDR),8)))
print ("MCNTRL_TEST01_STATUS_REG_CHN1_ADDR: %s"%(hx(self.read_status(self.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR),8)))
print ("MCNTRL_TEST01_STATUS_REG_CHN2_ADDR: %s"%(hx(self.read_status(self.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR),8)))
print ("MCNTRL_TEST01_STATUS_REG_CHN3_ADDR: %s"%(hx(self.read_status(self.MCNTRL_TEST01_STATUS_REG_CHN3_ADDR),8)))
print ("MCNTRL_TEST01_STATUS_REG_CHN4_ADDR: %s"%(hx(self.read_status(self.MCNTRL_TEST01_STATUS_REG_CHN4_ADDR),8)))
print ("MCONTR_PHY_STATUS_REG_ADDR: %s"%(hx(self.read_status(vrlg.MCONTR_PHY_STATUS_REG_ADDR),8)))
print ("MCONTR_TOP_STATUS_REG_ADDR: %s"%(hx(self.read_status(vrlg.MCONTR_TOP_STATUS_REG_ADDR),8)))
print ("MCNTRL_PS_STATUS_REG_ADDR: %s"%(hx(self.read_status(vrlg.MCNTRL_PS_STATUS_REG_ADDR) ,8)))
print ("MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR:%s"%(hx(self.read_status(vrlg.MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR),8)))
print ("MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR:%s"%(hx(self.read_status(vrlg.MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR),8)))
print ("MCNTRL_TILED_STATUS_REG_CHN2_ADDR: %s"%(hx(self.read_status(vrlg.MCNTRL_TILED_STATUS_REG_CHN2_ADDR),8)))
print ("MCNTRL_TILED_STATUS_REG_CHN4_ADDR: %s"%(hx(self.read_status(vrlg.MCNTRL_TILED_STATUS_REG_CHN4_ADDR),8)))
print ("MCNTRL_TEST01_STATUS_REG_CHN1_ADDR: %s"%(hx(self.read_status(vrlg.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR),8)))
print ("MCNTRL_TEST01_STATUS_REG_CHN2_ADDR: %s"%(hx(self.read_status(vrlg.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR),8)))
print ("MCNTRL_TEST01_STATUS_REG_CHN3_ADDR: %s"%(hx(self.read_status(vrlg.MCNTRL_TEST01_STATUS_REG_CHN3_ADDR),8)))
print ("MCNTRL_TEST01_STATUS_REG_CHN4_ADDR: %s"%(hx(self.read_status(vrlg.MCNTRL_TEST01_STATUS_REG_CHN4_ADDR),8)))
def program_status(self,
base_addr, # input [29:0] base_addr;
......@@ -195,17 +184,17 @@ class X393AxiControlStatus(object):
<seq_number> - 6-bit sequence number of the status message to be sent
"""
self.program_status (self.MCONTR_PHY_16BIT_ADDR, self.MCONTR_PHY_STATUS_CNTRL, mode,seq_num)# //MCONTR_PHY_STATUS_REG_ADDR= 'h0,
self.program_status (self.MCONTR_TOP_16BIT_ADDR, self.MCONTR_TOP_16BIT_STATUS_CNTRL, mode,seq_num)# //MCONTR_TOP_STATUS_REG_ADDR= 'h1,
self.program_status (self.MCNTRL_PS_ADDR, self.MCNTRL_PS_STATUS_CNTRL, mode,seq_num)# //MCNTRL_PS_STATUS_REG_ADDR= 'h2,
self.program_status (self.MCNTRL_SCANLINE_CHN1_ADDR, self.MCNTRL_SCANLINE_STATUS_CNTRL, mode,seq_num)#; //MCNTRL_SCANLINE_STATUS_REG_CHN2_ADDR='h4,
self.program_status (self.MCNTRL_SCANLINE_CHN3_ADDR, self.MCNTRL_SCANLINE_STATUS_CNTRL, mode,seq_num)# //MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR='h5,
self.program_status (self.MCNTRL_TILED_CHN2_ADDR, self.MCNTRL_TILED_STATUS_CNTRL, mode,seq_num)# //MCNTRL_TILED_STATUS_REG_CHN4_ADDR= 'h6,
self.program_status (self.MCNTRL_TILED_CHN4_ADDR, self.MCNTRL_TILED_STATUS_CNTRL, mode,seq_num)#; //MCNTRL_TILED_STATUS_REG_CHN4_ADDR= 'h6,
self.program_status (self.MCNTRL_TEST01_ADDR, self.MCNTRL_TEST01_CHN1_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN2_ADDR= 'h3c,
self.program_status (self.MCNTRL_TEST01_ADDR, self.MCNTRL_TEST01_CHN2_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN2_ADDR= 'h3c,
self.program_status (self.MCNTRL_TEST01_ADDR, self.MCNTRL_TEST01_CHN3_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN3_ADDR= 'h3d,
self.program_status (self.MCNTRL_TEST01_ADDR, self.MCNTRL_TEST01_CHN4_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN4_ADDR= 'h3e,
self.program_status (vrlg.MCONTR_PHY_16BIT_ADDR, vrlg.MCONTR_PHY_STATUS_CNTRL, mode,seq_num)# //MCONTR_PHY_STATUS_REG_ADDR= 'h0,
self.program_status (vrlg.MCONTR_TOP_16BIT_ADDR, vrlg.MCONTR_TOP_16BIT_STATUS_CNTRL, mode,seq_num)# //MCONTR_TOP_STATUS_REG_ADDR= 'h1,
self.program_status (vrlg.MCNTRL_PS_ADDR, vrlg.MCNTRL_PS_STATUS_CNTRL, mode,seq_num)# //MCNTRL_PS_STATUS_REG_ADDR= 'h2,
self.program_status (vrlg.MCNTRL_SCANLINE_CHN1_ADDR, vrlg.MCNTRL_SCANLINE_STATUS_CNTRL, mode,seq_num)#; //MCNTRL_SCANLINE_STATUS_REG_CHN2_ADDR='h4,
self.program_status (vrlg.MCNTRL_SCANLINE_CHN3_ADDR, vrlg.MCNTRL_SCANLINE_STATUS_CNTRL, mode,seq_num)# //MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR='h5,
self.program_status (vrlg.MCNTRL_TILED_CHN2_ADDR, vrlg.MCNTRL_TILED_STATUS_CNTRL, mode,seq_num)# //MCNTRL_TILED_STATUS_REG_CHN4_ADDR= 'h6,
self.program_status (vrlg.MCNTRL_TILED_CHN4_ADDR, vrlg.MCNTRL_TILED_STATUS_CNTRL, mode,seq_num)#; //MCNTRL_TILED_STATUS_REG_CHN4_ADDR= 'h6,
self.program_status (vrlg.MCNTRL_TEST01_ADDR, vrlg.MCNTRL_TEST01_CHN1_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN2_ADDR= 'h3c,
self.program_status (vrlg.MCNTRL_TEST01_ADDR, vrlg.MCNTRL_TEST01_CHN2_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN2_ADDR= 'h3c,
self.program_status (vrlg.MCNTRL_TEST01_ADDR, vrlg.MCNTRL_TEST01_CHN3_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN3_ADDR= 'h3d,
self.program_status (vrlg.MCNTRL_TEST01_ADDR, vrlg.MCNTRL_TEST01_CHN4_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN4_ADDR= 'h3e,
def enable_cmda(self,
en): # input en;
......@@ -213,7 +202,7 @@ class X393AxiControlStatus(object):
Enable (disable) address, bank and command lines to the DDR3 memory
<en> - 1 - enable, 0 - disable
"""
self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_CMDA_EN + en, 0);
self.write_contol_register(vrlg.MCONTR_PHY_0BIT_ADDR + vrlg.MCONTR_PHY_0BIT_CMDA_EN + en, 0);
def enable_cke(self,
en): # input en;
......@@ -221,7 +210,7 @@ class X393AxiControlStatus(object):
Enable (disable) CKE - clock enable to DDR3 memory
<en> - 1 - enable, 0 - disable
"""
self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_CKE_EN + en, 0);
self.write_contol_register(vrlg.MCONTR_PHY_0BIT_ADDR + vrlg.MCONTR_PHY_0BIT_CKE_EN + en, 0);
def activate_sdrst(self,
en): # input en;
......@@ -229,7 +218,7 @@ class X393AxiControlStatus(object):
Activate SDRST (reset) to DDR3 memory
<en> - 1 - activate (low), 0 - deactivate (high)
"""
self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_SDRST_ACT + en, 0);
self.write_contol_register(vrlg.MCONTR_PHY_0BIT_ADDR + vrlg.MCONTR_PHY_0BIT_SDRST_ACT + en, 0);
def enable_refresh(self,
en): # input en;
......@@ -237,7 +226,7 @@ class X393AxiControlStatus(object):
Enable (disable) refresh of the DDR3 memory
<en> - 1 - enable, 0 - disable
"""
self.write_contol_register(self.MCONTR_TOP_0BIT_ADDR + self.MCONTR_TOP_0BIT_REFRESH_EN + en, 0);
self.write_contol_register(vrlg.MCONTR_TOP_0BIT_ADDR + vrlg.MCONTR_TOP_0BIT_REFRESH_EN + en, 0);
def enable_memcntrl(self,
en): # input en;
......@@ -245,7 +234,7 @@ class X393AxiControlStatus(object):
Enable memory controller module
<en> - 1 - enable, 0 - disable
"""
self.write_contol_register(self.MCONTR_TOP_0BIT_ADDR + self.MCONTR_TOP_0BIT_MCONTR_EN + en, 0);
self.write_contol_register(vrlg.MCONTR_TOP_0BIT_ADDR + vrlg.MCONTR_TOP_0BIT_MCONTR_EN + en, 0);
def enable_memcntrl_channels(self,
chnen): # input [15:0] chnen; // bit-per-channel, 1 - enable;
......@@ -254,7 +243,7 @@ class X393AxiControlStatus(object):
<chnen> - 16-bit control word with per-channel enable bits (bit0 - chn0, ... bit15 - chn15)
"""
self.enabled_channels = chnen; # currently enabled memory channels
self.write_contol_register(self.MCONTR_TOP_16BIT_ADDR + self.MCONTR_TOP_16BIT_CHN_EN, self.enabled_channels & 0xffff) # {16'b0,chnen});
self.write_contol_register(vrlg.MCONTR_TOP_16BIT_ADDR + vrlg.MCONTR_TOP_16BIT_CHN_EN, self.enabled_channels & 0xffff) # {16'b0,chnen});
def enable_memcntrl_en_dis(self,
chn, # input [3:0] chn;
......@@ -268,7 +257,7 @@ class X393AxiControlStatus(object):
self.enabled_channels = self.enabled_channels | (1<<chn);
else:
self.enabled_channels = self.enabled_channels & ~(1<<chn);
self.write_contol_register(self.MCONTR_TOP_16BIT_ADDR + self. MCONTR_TOP_16BIT_CHN_EN, self.enabled_channels & 0xffff) # {16'b0,ENABLED_CHANNELS});
self.write_contol_register(vrlg.MCONTR_TOP_16BIT_ADDR + self. MCONTR_TOP_16BIT_CHN_EN, self.enabled_channels & 0xffff) # {16'b0,ENABLED_CHANNELS});
def configure_channel_priority(self,
chn, # input [ 3:0] chn;
......@@ -278,5 +267,5 @@ class X393AxiControlStatus(object):
<chn> - 4-bit channel select
<priority> - 16-bit priority value (higher value means more important)
"""
self.write_contol_register(self.MCONTR_ARBIT_ADDR + chn, priority & 0xffff)# {16'b0,priority});
self.write_contol_register(vrlg.MCONTR_ARBIT_ADDR + chn, priority & 0xffff)# {16'b0,priority});
......@@ -32,7 +32,7 @@ __status__ = "Development"
#import x393_mem
#x393_pio_sequences
import random
from import_verilog_parameters import VerilogParameters
#from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem
from x393_axi_control_status import X393AxiControlStatus
from x393_pio_sequences import X393PIOSequences
......@@ -44,6 +44,7 @@ from x393_mcntrl_buffers import X393McntrlBuffers
#from x393_axi_control_status import concat, bits
#from time import sleep
from verilog_utils import checkIntArgs,smooth2d
#import vrlg
NUM_FINE_STEPS= 5
class X393McntrlAdjust(object):
......@@ -63,11 +64,31 @@ class X393McntrlAdjust(object):
self.x393_pio_sequences= X393PIOSequences(debug_mode,dry_mode)
self.x393_mcntrl_timing= X393McntrlTiming(debug_mode,dry_mode)
self.x393_mcntrl_buffers= X393McntrlBuffers(debug_mode,dry_mode)
self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
# self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
try:
self.verbose=self.VERBOSE
except:
pass
#//SET DQ ODELAY=[['0xd9', '0xdb', '0xdc', '0xd4', '0xe0', '0xda', '0xd4', '0xd8'], ['0xdc', '0xe0', '0xf1', '0xdc', '0xe0', '0xdc', '0xdc', '0xdc']]
def format_dq_to_verilog(self,
estr):
"""
Convert dq delays list to the form to paste to the Verilog parameters code
<estr> quoted string, such as:
"[['0xd9', '0xdb', '0xdc', '0xd4', '0xe0', '0xda', '0xd4', '0xd8'], ['0xdc', '0xe0', '0xf1', '0xdc', '0xe0', '0xdc', '0xdc', '0xdc']]"
Returns a pair of strings to paste
"""
se=eval(estr) # now a list of list of strings
for l in se:
for i,v in enumerate(l):
l[i]=int(v,16)
for lane in range(2):
print("lane%d = 64'h"%lane,end="")
for i in range(len(se[lane])):
print("%02x"%se[lane][-i-1],end="")
print()
def split_delay(self,dly):
"""
......@@ -970,3 +991,7 @@ class X393McntrlAdjust(object):
min_diff, # minimal difference between primary delay steps to process
True, #adjust, not scan
verbose)
\ No newline at end of file
......@@ -31,13 +31,14 @@ __status__ = "Development"
#import sys
#import x393_mem
#x393_pio_sequences
from import_verilog_parameters import VerilogParameters
#from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem
from x393_axi_control_status import X393AxiControlStatus
#from verilog_utils import * # concat, bits
#from verilog_utils import hx, concat, bits, getParWidth
#from verilog_utils import concat, getParWidth
#from x393_axi_control_status import concat, bits
import vrlg
class X393McntrlBuffers(object):
DRY_MODE= True # True
DEBUG_MODE=1
......@@ -50,7 +51,7 @@ class X393McntrlBuffers(object):
self.DRY_MODE=dry_mode
self.x393_mem=X393Mem(debug_mode,dry_mode)
self.x393_axi_tasks=X393AxiControlStatus(debug_mode,dry_mode)
self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
# self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
try:
self.verbose=self.VERBOSE
except:
......@@ -71,14 +72,14 @@ class X393McntrlBuffers(object):
"""
if self.DEBUG_MODE > 1:
print("====== write_block_scanline_chn:%d page: %x X=0x%x Y=0x%x num=%dt"%(chn, page, startX, startY,num_bursts))
if chn == 0: start_addr=self.MCONTR_BUF0_WR_ADDR + (page << 8)
elif chn == 1: start_addr=self.MCONTR_BUF1_WR_ADDR + (page << 8)
elif chn == 2: start_addr=self.MCONTR_BUF2_WR_ADDR + (page << 8)
elif chn == 3: start_addr=self.MCONTR_BUF3_WR_ADDR + (page << 8)
elif chn == 4: start_addr=self.MCONTR_BUF4_WR_ADDR + (page << 8)
if chn == 0: start_addr=vrlg.MCONTR_BUF0_WR_ADDR + (page << 8)
elif chn == 1: start_addr=vrlg.MCONTR_BUF1_WR_ADDR + (page << 8)
elif chn == 2: start_addr=vrlg.MCONTR_BUF2_WR_ADDR + (page << 8)
elif chn == 3: start_addr=vrlg.MCONTR_BUF3_WR_ADDR + (page << 8)
elif chn == 4: start_addr=vrlg.MCONTR_BUF4_WR_ADDR + (page << 8)
else:
print("**** ERROR: Invalid channel for write_block_scanline_chn = %d"% chn)
start_addr = self.MCONTR_BUF0_WR_ADDR+ (page << 8);
start_addr = vrlg.MCONTR_BUF0_WR_ADDR+ (page << 8);
num_words=num_bursts << 2;
self.write_block_incremtal (start_addr, num_words, (startX<<2) + (startY<<16));# 1 of startX is 8x16 bit, 16 bytes or 4 32-bit words
......@@ -95,7 +96,7 @@ class X393McntrlBuffers(object):
xor=num_words_or_data_list[1]
num_words_or_data_list=num_words_or_data_list[0]
if isinstance (num_words_or_data_list,int):
if isinstance (num_words_or_data_list,(int,long)):
data=[]
for i in range(num_words_or_data_list):
data.append(xor ^(i | (((i + 7) & 0xff) << 8) | (((i + 23) & 0xff) << 16) | (((i + 31) & 0xff) << 24)))
......@@ -144,14 +145,14 @@ class X393McntrlBuffers(object):
print("=== [%s]"%str(num_words_or_data_list))
print("===")
start_addr=-1
if chn==0:start_addr=self.MCONTR_BUF0_WR_ADDR + (page << 8)
elif chn==1:start_addr=self.MCONTR_BUF1_WR_ADDR + (page << 8)
elif chn==2:start_addr=self.MCONTR_BUF2_WR_ADDR + (page << 8)
elif chn==3:start_addr=self.MCONTR_BUF3_WR_ADDR + (page << 8)
elif chn==4:start_addr=self.MCONTR_BUF4_WR_ADDR + (page << 8)
if chn==0:start_addr=vrlg.MCONTR_BUF0_WR_ADDR + (page << 8)
elif chn==1:start_addr=vrlg.MCONTR_BUF1_WR_ADDR + (page << 8)
elif chn==2:start_addr=vrlg.MCONTR_BUF2_WR_ADDR + (page << 8)
elif chn==3:start_addr=vrlg.MCONTR_BUF3_WR_ADDR + (page << 8)
elif chn==4:start_addr=vrlg.MCONTR_BUF4_WR_ADDR + (page << 8)
else:
print("**** ERROR: Invalid channel for write buffer = %d"% chn)
start_addr = self.MCONTR_BUF0_WR_ADDR+ (page << 8)
start_addr = vrlg.MCONTR_BUF0_WR_ADDR+ (page << 8)
self.write_block_buf (start_addr, num_words_or_data_list)
......@@ -189,13 +190,13 @@ class X393McntrlBuffers(object):
<show_rslt> print buffer data read
"""
start_addr=-1
if chn==0: start_addr=self.MCONTR_BUF0_RD_ADDR + (page << 8)
elif chn==1: start_addr=self.MCONTR_BUF1_RD_ADDR + (page << 8)
elif chn==2: start_addr=self.MCONTR_BUF2_RD_ADDR + (page << 8)
elif chn==3: start_addr=self.MCONTR_BUF3_RD_ADDR + (page << 8)
elif chn==4: start_addr=self.MCONTR_BUF4_RD_ADDR + (page << 8)
if chn==0: start_addr=vrlg.MCONTR_BUF0_RD_ADDR + (page << 8)
elif chn==1: start_addr=vrlg.MCONTR_BUF1_RD_ADDR + (page << 8)
elif chn==2: start_addr=vrlg.MCONTR_BUF2_RD_ADDR + (page << 8)
elif chn==3: start_addr=vrlg.MCONTR_BUF3_RD_ADDR + (page << 8)
elif chn==4: start_addr=vrlg.MCONTR_BUF4_RD_ADDR + (page << 8)
else:
print("**** ERROR: Invalid channel for read buffer = %d"%chn)
start_addr = self.MCONTR_BUF0_RD_ADDR+ (page << 8)
start_addr = vrlg.MCONTR_BUF0_RD_ADDR+ (page << 8)
result=self.read_block_buf (start_addr, num_read, show_rslt)
return result
......@@ -31,7 +31,7 @@ __status__ = "Development"
#import sys
#import x393_mem
#x393_pio_sequences
from import_verilog_parameters import VerilogParameters
#from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem
from x393_axi_control_status import X393AxiControlStatus
from x393_pio_sequences import X393PIOSequences
......@@ -43,6 +43,7 @@ from x393_mcntrl_adjust import X393McntrlAdjust
from verilog_utils import concat #, getParWidth
#from x393_axi_control_status import concat, bits
from time import sleep
import vrlg
class X393McntrlTests(object):
DRY_MODE= True # True
DEBUG_MODE=1
......@@ -61,7 +62,7 @@ class X393McntrlTests(object):
self.x393_mcntrl_timing= X393McntrlTiming(debug_mode,dry_mode)
self.x393_mcntrl_buffers= X393McntrlBuffers(debug_mode,dry_mode)
self.x393_mcntrl_adjust= X393McntrlAdjust(debug_mode,dry_mode)
self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
# self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
try:
self.verbose=self.VERBOSE
except:
......@@ -151,21 +152,21 @@ class X393McntrlTests(object):
self.x393_mcntrl_timing.axi_set_delays() # set all individual delays, aslo runs axi_set_phase()
else:
self.x393_mcntrl_timing.axi_set_same_delays(
self.DLY_DQ_IDELAY,
self.DLY_DQ_ODELAY,
self.DLY_DQS_IDELAY,
self.DLY_DQS_ODELAY,
self.DLY_DM_ODELAY,
self.DLY_CMDA_ODELAY)
vrlg.DLY_DQ_IDELAY,
vrlg.DLY_DQ_ODELAY,
vrlg.DLY_DQS_IDELAY,
vrlg.DLY_DQS_ODELAY,
vrlg.DLY_DM_ODELAY,
vrlg.DLY_CMDA_ODELAY)
# set clock phase relative to DDR clk
# print("Debugging: sleeping for 1 second")
# sleep(1)
phaseOK=self.x393_mcntrl_timing.axi_set_phase(self.DLY_PHASE,wait_phase_en=True); # wait for phase set
phaseOK=self.x393_mcntrl_timing.axi_set_phase(vrlg.DLY_PHASE,wait_phase_en=True); # wait for phase set
if not phaseOK:
print("Failed to set clock phase")
return 0
# read and print status (optional)
self.x393_mcntrl_timing.axi_set_wbuf_delay(self.WBUF_DLY_DFLT)
self.x393_mcntrl_timing.axi_set_wbuf_delay(vrlg.WBUF_DLY_DFLT)
self.x393_axi_tasks.read_all_status()
return 1
......@@ -177,8 +178,8 @@ class X393McntrlTests(object):
self.x393_pio_sequences.set_mrs(1) # reset DLL
if self.verbose>0: print("SET REFRESH")
self.x393_pio_sequences.set_refresh(
self.T_RFC, # input [ 9:0] t_rfc; # =50 for tCK=2.5ns
self.T_REFI) #input [ 7:0] t_refi; # 48/97 for normal, 16 - for simulation
vrlg.T_RFC, # input [ 9:0] t_rfc; # =50 for tCK=2.5ns
vrlg.T_REFI) #input [ 7:0] t_refi; # 48/97 for normal, 16 - for simulation
if self.verbose>0: print("SET WRITE LEVELING")
self.x393_pio_sequences.set_write_lev(16) # write leveling, 16 times (full buffer - 128)
if self.verbose>0: print("SET READ PATTERNt")
......@@ -218,15 +219,15 @@ class X393McntrlTests(object):
self.x393_pio_sequences.enable_reset_ps_pio(1,0) # enable, no reset
# set MR registers in DDR3 memory, run DCI calibration (long)
self.x393_pio_sequences.wait_ps_pio_ready(self.DEFAULT_STATUS_MODE, 1, 2.0); # wait FIFO not half full, sync sequences, timeout 2 sec
self.x393_pio_sequences.wait_ps_pio_ready(vrlg.DEFAULT_STATUS_MODE, 1, 2.0); # wait FIFO not half full, sync sequences, timeout 2 sec
self.x393_pio_sequences.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.INITIALIZE_OFFSET, # input [9:0] seq_addr; # sequence start address
vrlg.INITIALIZE_OFFSET, # input [9:0] seq_addr; # sequence start address
0, # input [1:0] page; # buffer page number
0, # input urgent; # high priority request (only for competion with other channels, wiil not pass in this FIFO)
0, # input chn; # channel buffer to use: 0 - memory read, 1 - memory write
wait_complete ); # wait_complete; # Do not request a newe transaction from the scheduler until previous memory transaction is finished
# Wait PS PIO sequence DOEN
self.x393_pio_sequences.wait_ps_pio_done(self.DEFAULT_STATUS_MODE, 1 , 2.0); # wait FIFO not half full, sync sequences, timeout 2 sec
self.x393_pio_sequences.wait_ps_pio_done(vrlg.DEFAULT_STATUS_MODE, 1 , 2.0); # wait FIFO not half full, sync sequences, timeout 2 sec
self.x393_axi_tasks.enable_refresh(1)
# axi_set_dqs_odelay('h78); #??? defaults - wrong? DLY_DQS_ODELAY=0x74
......@@ -244,22 +245,22 @@ class X393McntrlTests(object):
"""
numBufWords=32 # twice nrep in set_write_lev
if norm_dqs_odly is None:
norm_dqs_odly=self.DLY_DQS_ODELAY
norm_dqs_odly=vrlg.DLY_DQS_ODELAY
# Set special values for DQS idelay for write leveling
self.x393_pio_sequences.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1); # not no interrupt running cycle - delays are changed immediately
self.x393_pio_sequences.wait_ps_pio_done(vrlg.DEFAULT_STATUS_MODE,1); # not no interrupt running cycle - delays are changed immediately
## self.x393_mcntrl_timing.axi_set_dqs_idelay_wlv()
# Set write buffer (from DDR3) WE signal delay for write leveling mode
## self.x393_mcntrl_timing.axi_set_wbuf_delay(self.WBUF_DLY_WLV)
## self.x393_mcntrl_timing.axi_set_wbuf_delay(vrlg.WBUF_DLY_WLV)
# TODO: Set configurable delay time instead of #80
## self.x393_mcntrl_timing.axi_set_dqs_odelay(wlev_dqs_dly) # 'h80); # 'h80 - inverted, 'h60 - not - 'h80 will cause warnings during simulation
self.x393_pio_sequences.schedule_ps_pio (# schedule software-control memory operation (may need to check FIFO status first)
self.WRITELEV_OFFSET, # input [9:0] seq_addr; # sequence start address
vrlg.WRITELEV_OFFSET, # input [9:0] seq_addr; # sequence start address
0, # input [1:0] page; # buffer page number
0, # input urgent; # high priority request (only for competition with other channels, will not pass in this FIFO)
0, # input chn; # channel buffer to use: 0 - memory read, 1 - memory write
wait_complete) # `PS_PIO_WAIT_COMPLETE );# wait_complete; # Do not request a newe transaction from the scheduler until previous memory transaction is finished
self.x393_pio_sequences.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1); # wait previous memory transaction finished before changing delays (effective immediately)
self.x393_pio_sequences.wait_ps_pio_done(vrlg.DEFAULT_STATUS_MODE,1); # wait previous memory transaction finished before changing delays (effective immediately)
buf=self.x393_mcntrl_buffers.read_block_buf_chn (0, 0, numBufWords, (0,1)[self.verbose>1]) # chn=0, page=0, number of 32-bit words=32, show_rslt
#calculate 1-s ratio for both lanes
rslt=[0.0,0.0]
......@@ -269,7 +270,7 @@ class X393McntrlTests(object):
rslt[i]/=2*numBufWords
## self.x393_mcntrl_timing.axi_set_dqs_idelay_nominal()
## self.x393_mcntrl_timing.axi_set_dqs_odelay(norm_dqs_odly) # 'h78);
## self.x393_mcntrl_timing.axi_set_wbuf_delay(self.WBUF_DLY_DFLT); #DFLT_WBUF_DELAY
## self.x393_mcntrl_timing.axi_set_wbuf_delay(vrlg.WBUF_DLY_DFLT); #DFLT_WBUF_DELAY
return rslt
def test_read_pattern(self,
......@@ -388,25 +389,25 @@ class X393McntrlTests(object):
"""
# integer startx,starty; # temporary - because of the vdt bug with integer ports
# pages_per_row= (window_width>>NUM_XFER_BITS)+((window_width[NUM_XFER_BITS-1:0]==0)?0:1);
pages_per_row= (window_width>>self.NUM_XFER_BITS)+(0,1)[(window_width & ((1<<self.NUM_XFER_BITS))-1)==0] # (window_width>>NUM_XFER_BITS)+((window_width[NUM_XFER_BITS-1:0]==0)?0:1);
pages_per_row= (window_width>>vrlg.NUM_XFER_BITS)+(0,1)[(window_width & ((1<<vrlg.NUM_XFER_BITS))-1)==0] # (window_width>>NUM_XFER_BITS)+((window_width[NUM_XFER_BITS-1:0]==0)?0:1);
print("====== test_scanline_write: channel=%d, extra_pages=%d, wait_done=%d"%
(channel, extra_pages, wait_done))
if channel == 1:
start_addr= self.MCNTRL_SCANLINE_CHN1_ADDR
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_STATUS_CNTRL
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_MODE
start_addr= vrlg.MCNTRL_SCANLINE_CHN1_ADDR
status_address= vrlg.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR
status_control_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN1_STATUS_CNTRL
test_mode_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN1_MODE
elif channel == 3:
start_addr= self.MCNTRL_SCANLINE_CHN3_ADDR
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN3_ADDR
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN3_STATUS_CNTRL
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN3_MODE
start_addr= vrlg.MCNTRL_SCANLINE_CHN3_ADDR
status_address= vrlg.MCNTRL_TEST01_STATUS_REG_CHN3_ADDR
status_control_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN3_STATUS_CNTRL
test_mode_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN3_MODE
else:
print("**** ERROR: Invalid channel, only 1 and 3 are valid")
start_addr= self.MCNTRL_SCANLINE_CHN1_ADDR
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_STATUS_CNTRL
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_MODE
start_addr= vrlg.MCNTRL_SCANLINE_CHN1_ADDR
status_address= vrlg.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR
status_control_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN1_STATUS_CNTRL
test_mode_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN1_MODE
mode= self.func_encode_mode_scanline(
extra_pages,
......@@ -414,28 +415,28 @@ class X393McntrlTests(object):
1, # enable
0) # chn_reset
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_STARTADDR, self.FRAME_START_ADDRESS); # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_FRAME_FULL_WIDTH, self.FRAME_FULL_WIDTH);
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_WINDOW_WH, {window_height,window_width}); #WINDOW_WIDTH + (WINDOW_HEIGHT<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_WINDOW_X0Y0, {window_top,window_left}); #WINDOW_X0+ (WINDOW_Y0<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_WINDOW_STARTXY, self.SCANLINE_STARTX+(self.SCANLINE_STARTY<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_MODE, mode);
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_SCANLINE_STARTADDR, vrlg.FRAME_START_ADDRESS); # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_SCANLINE_FRAME_FULL_WIDTH, vrlg.FRAME_FULL_WIDTH);
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_SCANLINE_WINDOW_WH, {window_height,window_width}); #WINDOW_WIDTH + (WINDOW_HEIGHT<<16));
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_SCANLINE_WINDOW_X0Y0, {window_top,window_left}); #WINDOW_X0+ (WINDOW_Y0<<16));
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_SCANLINE_WINDOW_STARTXY, vrlg.SCANLINE_STARTX+(vrlg.SCANLINE_STARTY<<16));
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_SCANLINE_MODE, mode);
self.x393_axi_tasks.configure_channel_priority(channel,0); # lowest priority channel 3
# enable_memcntrl_channels(16'h000b); # channels 0,1,3 are enabled
self.x393_axi_tasks.enable_memcntrl_en_dis(channel,1);
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_START_FRAME);
for ii in range(0,self.TEST_INITIAL_BURST): # for (ii=0;ii<TEST_INITIAL_BURST;ii=ii+1) begin
self.x393_axi_tasks.write_contol_register(test_mode_address, vrlg.TEST01_START_FRAME);
for ii in range(0,vrlg.TEST_INITIAL_BURST): # for (ii=0;ii<TEST_INITIAL_BURST;ii=ii+1) begin
# VDT bugs: 1:does not propagate undefined width through ?:, 2: - does not allow to connect it to task integer input, 3: shows integer input width as 1
if pages_per_row > 1:
if (ii % pages_per_row) < (pages_per_row-1):
xfer_size= 1 << self.NUM_XFER_BITS
xfer_size= 1 << vrlg.NUM_XFER_BITS
else:
xfer_size= window_width % (1<<self.NUM_XFER_BITS)
xfer_size= window_width % (1<<vrlg.NUM_XFER_BITS)
else:
xfer_size= window_width & 0xffff
print("########### test_scanline_write block %d: channel=%d"%(ii, channel));
startx=window_left + ((ii % pages_per_row) << self.NUM_XFER_BITS)
startx=window_left + ((ii % pages_per_row) << vrlg.NUM_XFER_BITS)
starty=window_top + (ii / pages_per_row);
self.x393_mcntrl_buffers.write_block_scanline_chn(
channel,
......@@ -445,25 +446,25 @@ class X393McntrlTests(object):
starty) # window_top + (ii / pages_per_row)); # SCANLINE_CUR_Y);\
for ii in range(window_height * pages_per_row): # for (ii=0;ii< (window_height * pages_per_row) ;ii = ii+1) begin # here assuming 1 page per line
if (ii >= self.TEST_INITIAL_BURST): # begin # wait page ready and fill page after first 4 are filled
if (ii >= vrlg.TEST_INITIAL_BURST): # begin # wait page ready and fill page after first 4 are filled
self.x393_axi_tasks.wait_status_condition (
status_address, # MCNTRL_TEST01_STATUS_REG_CHN3_ADDR,
status_control_address, # MCNTRL_TEST01_ADDR + MCNTRL_TEST01_CHN3_STATUS_CNTRL,
self.DEFAULT_STATUS_MODE,
(ii-self.TEST_INITIAL_BURST)<<16, # 4-bit page number
vrlg.DEFAULT_STATUS_MODE,
(ii-vrlg.TEST_INITIAL_BURST)<<16, # 4-bit page number
0xf << 16, #'hf << 16, # mask for the 4-bit page number
1, # not equal to
(0,1)[ii == self.TEST_INITIAL_BURST]) # synchronize sequence number - only first time, next just wait fro auto update
(0,1)[ii == vrlg.TEST_INITIAL_BURST]) # synchronize sequence number - only first time, next just wait fro auto update
if pages_per_row > 1:
if (ii % pages_per_row) < (pages_per_row-1):
xfer_size= 1 << self.NUM_XFER_BITS
xfer_size= 1 << vrlg.NUM_XFER_BITS
else:
xfer_size= window_width % (1<<self.NUM_XFER_BITS)
xfer_size= window_width % (1<<vrlg.NUM_XFER_BITS)
else:
xfer_size= window_width & 0xffff
print("########### test_scanline_write block %d: channel=%d"%(ii, channel));
startx=window_left + ((ii % pages_per_row) << self.NUM_XFER_BITS);
startx=window_left + ((ii % pages_per_row) << vrlg.NUM_XFER_BITS);
starty=window_top + (ii / pages_per_row);
self.x393_mcntrl_buffers.write_block_scanline_chn(
channel,
......@@ -471,14 +472,14 @@ class X393McntrlTests(object):
xfer_size,
startx, # window_left + ((ii % pages_per_row)<<NUM_XFER_BITS), # SCANLINE_CUR_X,
starty) # window_top + (ii / pages_per_row)); # SCANLINE_CUR_Y);
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_NEXT_PAGE)
self.x393_axi_tasks.write_contol_register(test_mode_address, vrlg.TEST01_NEXT_PAGE)
if wait_done:
self.x393_axi_tasks.wait_status_condition ( # may also be read directly from the same bit of mctrl_linear_rw (address=5) status
status_address, # MCNTRL_TEST01_STATUS_REG_CHN3_ADDR,
status_control_address, # MCNTRL_TEST01_ADDR + MCNTRL_TEST01_CHN3_STATUS_CNTRL,
self.DEFAULT_STATUS_MODE,
2 << self.STATUS_2LSB_SHFT, # bit 24 - busy, bit 25 - frame done
2 << self.STATUS_2LSB_SHFT, # mask for the 4-bit page number
vrlg.DEFAULT_STATUS_MODE,
2 << vrlg.STATUS_2LSB_SHFT, # bit 24 - busy, bit 25 - frame done
2 << vrlg.STATUS_2LSB_SHFT, # mask for the 4-bit page number
0, # equal to
0); # no need to synchronize sequence number
# enable_memcntrl_en_dis(channel,0); # disable channel
......@@ -506,53 +507,53 @@ class X393McntrlTests(object):
result=[] # will be a 2-d array
# pages_per_row= (window_width>>NUM_XFER_BITS)+((window_width[NUM_XFER_BITS-1:0]==0)?0:1);
pages_per_row= (window_width>>self.NUM_XFER_BITS)+(0,1)[(window_width & ((1<<self.NUM_XFER_BITS))-1)==0] # (window_width>>NUM_XFER_BITS)+((window_width[NUM_XFER_BITS-1:0]==0)?0:1);
pages_per_row= (window_width>>vrlg.NUM_XFER_BITS)+(0,1)[(window_width & ((1<<vrlg.NUM_XFER_BITS))-1)==0] # (window_width>>NUM_XFER_BITS)+((window_width[NUM_XFER_BITS-1:0]==0)?0:1);
print("====== test_scanline_read: channel=%d, extra_pages=%d, show_data=%d"%
(channel, extra_pages, show_data))
if channel == 1:
start_addr= self.MCNTRL_SCANLINE_CHN1_ADDR
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_STATUS_CNTRL
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_MODE
start_addr= vrlg.MCNTRL_SCANLINE_CHN1_ADDR
status_address= vrlg.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR
status_control_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN1_STATUS_CNTRL
test_mode_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN1_MODE
elif channel == 3:
start_addr= self.MCNTRL_SCANLINE_CHN3_ADDR
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN3_ADDR
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN3_STATUS_CNTRL
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN3_MODE
start_addr= vrlg.MCNTRL_SCANLINE_CHN3_ADDR
status_address= vrlg.MCNTRL_TEST01_STATUS_REG_CHN3_ADDR
status_control_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN3_STATUS_CNTRL
test_mode_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN3_MODE
else:
print("**** ERROR: Invalid channel, only 1 and 3 are valid")
start_addr= self.MCNTRL_SCANLINE_CHN1_ADDR
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_STATUS_CNTRL
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_MODE
start_addr= vrlg.MCNTRL_SCANLINE_CHN1_ADDR
status_address= vrlg.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR
status_control_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN1_STATUS_CNTRL
test_mode_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN1_MODE
mode= self.func_encode_mode_scanline(
extra_pages,
0, # write_mem,
1, # enable
0) # chn_reset
# program to the
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_STARTADDR, self.FRAME_START_ADDRESS); # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_FRAME_FULL_WIDTH, self.FRAME_FULL_WIDTH);
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_WINDOW_WH, {window_height,window_width}); #WINDOW_WIDTH + (WINDOW_HEIGHT<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_WINDOW_X0Y0, {window_top,window_left}); #WINDOW_X0+ (WINDOW_Y0<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_WINDOW_STARTXY, self.SCANLINE_STARTX+(self.SCANLINE_STARTY<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_MODE, mode);# set mode register: {extra_pages[1:0],enable,!reset}
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_SCANLINE_STARTADDR, vrlg.FRAME_START_ADDRESS); # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_SCANLINE_FRAME_FULL_WIDTH, vrlg.FRAME_FULL_WIDTH);
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_SCANLINE_WINDOW_WH, {window_height,window_width}); #WINDOW_WIDTH + (WINDOW_HEIGHT<<16));
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_SCANLINE_WINDOW_X0Y0, {window_top,window_left}); #WINDOW_X0+ (WINDOW_Y0<<16));
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_SCANLINE_WINDOW_STARTXY, vrlg.SCANLINE_STARTX+(vrlg.SCANLINE_STARTY<<16));
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_SCANLINE_MODE, mode);# set mode register: {extra_pages[1:0],enable,!reset}
self.x393_axi_tasks.configure_channel_priority(channel,0); # lowest priority channel 3
self.x393_axi_tasks.enable_memcntrl_en_dis(channel,1);
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_START_FRAME);
self.x393_axi_tasks.write_contol_register(test_mode_address, vrlg.TEST01_START_FRAME);
for ii in range(window_height * pages_per_row): # for (ii=0;ii<(window_height * pages_per_row);ii = ii+1) begin
if pages_per_row > 1:
if (ii % pages_per_row) < (pages_per_row-1):
xfer_size= 1 << self.NUM_XFER_BITS
xfer_size= 1 << vrlg.NUM_XFER_BITS
else:
xfer_size= window_width % (1<<self.NUM_XFER_BITS)
xfer_size= window_width % (1<<vrlg.NUM_XFER_BITS)
else:
xfer_size= window_width & 0xffff
self.x393_axi_tasks.wait_status_condition (
status_address, #MCNTRL_TEST01_STATUS_REG_CHN2_ADDR,
status_control_address, # MCNTRL_TEST01_ADDR + MCNTRL_TEST01_CHN2_STATUS_CNTRL,
self.DEFAULT_STATUS_MODE,
vrlg.DEFAULT_STATUS_MODE,
(ii) << 16, # -TEST_INITIAL_BURST)<<16, # 4-bit page number
0xf << 16, #'hf << 16, # mask for the 4-bit page number
1, # not equal to
......@@ -566,7 +567,7 @@ class X393McntrlTests(object):
xfer_size <<2,
# 1, # chn=0, page=3, number of 32-bit words=256, show_rslt
show_data))
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_NEXT_PAGE)
self.x393_axi_tasks.write_contol_register(test_mode_address, vrlg.TEST01_NEXT_PAGE)
return result
def test_tiled_write(self, #
......@@ -609,21 +610,21 @@ class X393McntrlTests(object):
print("====== test_tiled_write: channel=%d, byte32=%d, keep_open=%d, extra_pages=%d, wait_done=%d"%
(channel, byte32, keep_open, extra_pages, wait_done))
if channel == 2:
start_addr= self.MCNTRL_TILED_CHN2_ADDR
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_STATUS_CNTRL
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_MODE
start_addr= vrlg.MCNTRL_TILED_CHN2_ADDR
status_address= vrlg.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR
status_control_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN2_STATUS_CNTRL
test_mode_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN2_MODE
elif channel == 4:
start_addr= self.MCNTRL_TILED_CHN4_ADDR;
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN4_ADDR;
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN4_STATUS_CNTRL;
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN4_MODE;
start_addr= vrlg.MCNTRL_TILED_CHN4_ADDR;
status_address= vrlg.MCNTRL_TEST01_STATUS_REG_CHN4_ADDR;
status_control_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN4_STATUS_CNTRL;
test_mode_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN4_MODE;
else:
print("**** ERROR: Invalid channel, only 2 and 4 are valid");
start_addr= self.MCNTRL_TILED_CHN2_ADDR;
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR;
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_STATUS_CNTRL;
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_MODE;
start_addr= vrlg.MCNTRL_TILED_CHN2_ADDR;
status_address= vrlg.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR;
status_control_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN2_STATUS_CNTRL;
test_mode_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN2_MODE;
mode= self.func_encode_mode_tiled(
byte32,
keep_open,
......@@ -631,29 +632,29 @@ class X393McntrlTests(object):
1, # write_mem,
1, # enable
0) # chn_reset
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_STARTADDR,
self.FRAME_START_ADDRESS) # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_FRAME_FULL_WIDTH,
self.FRAME_FULL_WIDTH)
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_WINDOW_WH,
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_TILED_STARTADDR,
vrlg.FRAME_START_ADDRESS) # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_TILED_FRAME_FULL_WIDTH,
vrlg.FRAME_FULL_WIDTH)
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_TILED_WINDOW_WH,
concat(((window_height,16),
(window_width, 16)))) # {window_height,window_width});
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_WINDOW_X0Y0,
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_TILED_WINDOW_X0Y0,
concat(((window_top, 16),
(window_left, 16)))) # {window_top,window_left});
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_WINDOW_STARTXY,
concat(((self.TILED_STARTY, 16),
(self.TILED_STARTX, 16)))) # TILED_STARTX+(TILED_STARTY<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_TILE_WHS,
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_TILED_WINDOW_STARTXY,
concat(((vrlg.TILED_STARTY, 16),
(vrlg.TILED_STARTX, 16)))) # TILED_STARTX+(TILED_STARTY<<16));
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_TILED_TILE_WHS,
concat(((tile_vstep, 8),
(tile_height, 8),
(tile_width, 8)))) # {8'b0,tile_vstep,tile_height,tile_width});#tile_width+(tile_height<<8)+(tile_vstep<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_MODE, mode);# set mode register: {extra_pages[1:0],enable,!reset}
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_TILED_MODE, mode);# set mode register: {extra_pages[1:0],enable,!reset}
self.x393_axi_tasks.configure_channel_priority(channel,0) # lowest priority channel 3
self.x393_axi_tasks.enable_memcntrl_en_dis(channel,1);
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_START_FRAME);
self.x393_axi_tasks.write_contol_register(test_mode_address, vrlg.TEST01_START_FRAME);
for ii in range(self.TEST_INITIAL_BURST): # for (ii=0;ii<TEST_INITIAL_BURST;ii=ii+1) begin
for ii in range(vrlg.TEST_INITIAL_BURST): # for (ii=0;ii<TEST_INITIAL_BURST;ii=ii+1) begin
print("########### test_tiled_write block %d: channel=%d"%( ii, channel))
startx = window_left + ((ii % tiles_per_row) * tile_width)
starty = window_top + (ii / tile_rows_per_window) # SCANLINE_CUR_Y);
......@@ -665,15 +666,15 @@ class X393McntrlTests(object):
starty); #window_top + (ii / tile_rows_per_window)); # SCANLINE_CUR_Y);\
for ii in range(tiles_per_row * tile_rows_per_window): # for (ii=0;ii<(tiles_per_row * tile_rows_per_window);ii = ii+1) begin
if ii >= self.TEST_INITIAL_BURST: # ) begin # wait page ready and fill page after first 4 are filled
if ii >= vrlg.TEST_INITIAL_BURST: # ) begin # wait page ready and fill page after first 4 are filled
self.x393_axi_tasks.wait_status_condition (
status_address, # MCNTRL_TEST01_STATUS_REG_CHN5_ADDR,
status_control_address, # MCNTRL_TEST01_ADDR + MCNTRL_TEST01_CHN5_STATUS_CNTRL,
self.DEFAULT_STATUS_MODE,
(ii-self.TEST_INITIAL_BURST)<<16, # 4-bit page number
vrlg.DEFAULT_STATUS_MODE,
(ii-vrlg.TEST_INITIAL_BURST)<<16, # 4-bit page number
0xf << 16, # 'hf << 16, # mask for the 4-bit page number
1, # not equal to
(0,1)[ii == self.TEST_INITIAL_BURST]); # synchronize sequence number - only first time, next just wait fro auto update
(0,1)[ii == vrlg.TEST_INITIAL_BURST]); # synchronize sequence number - only first time, next just wait fro auto update
print("########### test_tiled_write block %d: channel=%d"%(ii, channel))
startx = window_left + ((ii % tiles_per_row) * tile_width);
starty = window_top + (ii / tile_rows_per_window);
......@@ -683,14 +684,14 @@ class X393McntrlTests(object):
tile_size,
startx, # window_left + ((ii % tiles_per_row) * tile_width),
starty) # window_top + (ii / tile_rows_per_window)); # SCANLINE_CUR_Y);\
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_NEXT_PAGE);
self.x393_axi_tasks.write_contol_register(test_mode_address, vrlg.TEST01_NEXT_PAGE);
if wait_done:
self.x393_axi_tasks.wait_status_condition( # may also be read directly from the same bit of mctrl_linear_rw (address=5) status
status_address, # MCNTRL_TEST01_STATUS_REG_CHN3_ADDR,
status_control_address, # MCNTRL_TEST01_ADDR + MCNTRL_TEST01_CHN3_STATUS_CNTRL,
self.DEFAULT_STATUS_MODE,
2 << self.STATUS_2LSB_SHFT, # bit 24 - busy, bit 25 - frame done
2 << self.STATUS_2LSB_SHFT, # mask for the 4-bit page number
vrlg.DEFAULT_STATUS_MODE,
2 << vrlg.STATUS_2LSB_SHFT, # bit 24 - busy, bit 25 - frame done
2 << vrlg.STATUS_2LSB_SHFT, # mask for the 4-bit page number
0, # equal to
0) # no need to synchronize sequence number
# enable_memcntrl_en_dis(channel,0); # disable channel
......@@ -735,21 +736,21 @@ class X393McntrlTests(object):
print("====== test_tiled_read: channel=%d, byte32=%d, keep_open=%d, extra_pages=%d, show_data=%d"%
(channel, byte32, keep_open, extra_pages, show_data))
if channel == 2:
start_addr= self.MCNTRL_TILED_CHN2_ADDR;
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR;
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_STATUS_CNTRL;
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_MODE;
start_addr= vrlg.MCNTRL_TILED_CHN2_ADDR;
status_address= vrlg.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR;
status_control_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN2_STATUS_CNTRL;
test_mode_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN2_MODE;
elif channel == 4:
start_addr= self.MCNTRL_TILED_CHN4_ADDR;
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN4_ADDR;
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN4_STATUS_CNTRL;
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN4_MODE;
start_addr= vrlg.MCNTRL_TILED_CHN4_ADDR;
status_address= vrlg.MCNTRL_TEST01_STATUS_REG_CHN4_ADDR;
status_control_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN4_STATUS_CNTRL;
test_mode_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN4_MODE;
else:
print("**** ERROR: Invalid channel, only 2 and 4 are valid");
start_addr= self.MCNTRL_TILED_CHN2_ADDR;
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR;
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_STATUS_CNTRL;
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_MODE;
start_addr= vrlg.MCNTRL_TILED_CHN2_ADDR;
status_address= vrlg.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR;
status_control_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN2_STATUS_CNTRL;
test_mode_address= vrlg.MCNTRL_TEST01_ADDR + vrlg.MCNTRL_TEST01_CHN2_MODE;
mode= self.func_encode_mode_tiled(
byte32,
......@@ -758,32 +759,32 @@ class X393McntrlTests(object):
0, # write_mem,
1, # enable
0) # chn_reset
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_STARTADDR,
self.FRAME_START_ADDRESS) # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_FRAME_FULL_WIDTH,
self.FRAME_FULL_WIDTH)
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_WINDOW_WH,
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_TILED_STARTADDR,
vrlg.FRAME_START_ADDRESS) # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_TILED_FRAME_FULL_WIDTH,
vrlg.FRAME_FULL_WIDTH)
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_TILED_WINDOW_WH,
concat(((window_height,16),
(window_width, 16)))) # {window_height,window_width});
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_WINDOW_X0Y0,
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_TILED_WINDOW_X0Y0,
concat(((window_top, 16),
(window_left, 16)))) # {window_top,window_left});
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_WINDOW_STARTXY,
concat(((self.TILED_STARTY, 16),
(self.TILED_STARTX, 16)))) # TILED_STARTX+(TILED_STARTY<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_TILE_WHS,
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_TILED_WINDOW_STARTXY,
concat(((vrlg.TILED_STARTY, 16),
(vrlg.TILED_STARTX, 16)))) # TILED_STARTX+(TILED_STARTY<<16));
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_TILED_TILE_WHS,
concat(((tile_vstep, 8),
(tile_height, 8),
(tile_width, 8)))) # {8'b0,tile_vstep,tile_height,tile_width});#tile_width+(tile_height<<8)+(tile_vstep<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_MODE, mode);# set mode register: {extra_pages[1:0],enable,!reset}
self.x393_axi_tasks.write_contol_register(start_addr + vrlg.MCNTRL_TILED_MODE, mode);# set mode register: {extra_pages[1:0],enable,!reset}
self.x393_axi_tasks.configure_channel_priority(channel,0) # lowest priority channel 3
self.x393_axi_tasks.enable_memcntrl_en_dis(channel,1);
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_START_FRAME);
self.x393_axi_tasks.write_contol_register(test_mode_address, vrlg.TEST01_START_FRAME);
for ii in range(tiles_per_row * tile_rows_per_window): # (ii=0;ii<(tiles_per_row * tile_rows_per_window);ii = ii+1) begin
self.x393_axi_tasks.wait_status_condition (
status_address, # MCNTRL_TEST01_STATUS_REG_CHN4_ADDR,
status_control_address, # MCNTRL_TEST01_ADDR + MCNTRL_TEST01_CHN4_STATUS_CNTRL,
self.DEFAULT_STATUS_MODE,
vrlg.DEFAULT_STATUS_MODE,
ii << 16, # -TEST_INITIAL_BURST)<<16, # 4-bit page number
0xf<< 16, #'hf << 16, # mask for the 4-bit page number
1, # not equal to
......@@ -796,6 +797,6 @@ class X393McntrlTests(object):
tile_size <<2,
# 1, # chn=0, page=3, number of 32-bit words=256, show_rslt
show_data))
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_NEXT_PAGE);
self.x393_axi_tasks.write_contol_register(test_mode_address, vrlg.TEST01_NEXT_PAGE);
# enable_memcntrl_en_dis(channel,0); # disable channel
return result
......@@ -31,43 +31,51 @@ __status__ = "Development"
#import sys
#import x393_mem
#x393_pio_sequences
from import_verilog_parameters import VerilogParameters
#from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem
from x393_axi_control_status import X393AxiControlStatus
#from verilog_utils import * # concat, bits
#from verilog_utils import hx, concat, bits, getParWidth
from verilog_utils import concat, getParWidth,hexMultiple
#from x393_axi_control_status import concat, bits
import vrlg # global parameters
#from x393_utils import X393Utils
class X393McntrlTiming(object):
DRY_MODE= True # True
DEBUG_MODE=1
# vpars=None
x393_mem=None
x393_axi_tasks=None #x393X393AxiControlStatus
target_phase=0 # TODO: set!
x393_utils=None
# target_phase=0 # TODO: set!
def __init__(self, debug_mode=1,dry_mode=True):
self.DEBUG_MODE=debug_mode
self.DRY_MODE=dry_mode
self.x393_mem=X393Mem(debug_mode,dry_mode)
self.x393_axi_tasks=X393AxiControlStatus(debug_mode,dry_mode)
self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
# vrlg=X393Utils(debug_mode,dry_mode)
# self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
def axi_set_phase(self,
phase, # input [PHASE_WIDTH-1:0] phase;
phase=None, # input [PHASE_WIDTH-1:0] phase;
wait_phase_en=True,
wait_seq=False):
"""
Set clock phase
<phase> 8-bit clock phase value
<phase> 8-bit clock phase value (None will use default)
<wait_phase_en> compare phase shift to programmed (will not work if the program was restarted)
<wait_seq> read and re-send status request to make sure status reflects new data (just for testing, too fast for Python)
Returns 1 if success, 0 if timeout (or no wait was performed)
"""
if phase is None:
phase= vrlg.get_default("DLY_PHASE")
vrlg.DLY_PHASE=phase & ((1<<vrlg.PHASE_WIDTH)-1)
if self.DEBUG_MODE > 1:
print("SET CLOCK PHASE=0x%x"%phase)
self.x393_axi_tasks.write_contol_register(self.LD_DLY_PHASE, phase & ((1<<self.PHASE_WIDTH)-1)) # {{(32-PHASE_WIDTH){1'b0}},phase}); // control regiter address
self.x393_axi_tasks.write_contol_register(self.DLY_SET,0)
self.target_phase = phase
print("SET CLOCK PHASE=0x%x"%(vrlg.DLY_PHASE))
self.x393_axi_tasks.write_contol_register(vrlg.LD_DLY_PHASE,vrlg.DLY_PHASE) # {{(32-PHASE_WIDTH){1'b0}},phase}); // control register address
self.x393_axi_tasks.write_contol_register(vrlg.DLY_SET,0)
# self.target_phase = phase
if wait_phase_en:
return self.wait_phase(True, wait_seq)
return 0
......@@ -81,13 +89,13 @@ class X393McntrlTiming(object):
<wait_seq> read and re-send status request to make sure status reflects new data (just for testing, too fast for Python)
Returns 1 if success, 0 if timeout
"""
patt = 0x3000000 | self.target_phase
patt = 0x3000000 | vrlg.DLY_PHASE
mask = 0x3000100
if check_phase_value:
mask |= 0xff
return self.x393_axi_tasks.wait_status_condition(
self.MCONTR_PHY_STATUS_REG_ADDR, # status_address,
self.MCONTR_PHY_16BIT_ADDR + self.MCONTR_PHY_STATUS_CNTRL, # status_control_address,
vrlg.MCONTR_PHY_STATUS_REG_ADDR, # status_address,
vrlg.MCONTR_PHY_16BIT_ADDR + vrlg.MCONTR_PHY_STATUS_CNTRL, # status_control_address,
3, # status_mode,
patt, # pattern,
mask, # mask
......@@ -100,7 +108,7 @@ class X393McntrlTiming(object):
"""
Returns previously set clock phase value
"""
return self.target_phase
return vrlg.DLY_PHASE
def axi_set_same_delays(self, #
dq_idelay, # input [7:0] dq_idelay;
dq_odelay, # input [7:0] dq_odelay;
......@@ -129,217 +137,237 @@ class X393McntrlTiming(object):
self.axi_set_dm_odelay(dm_odelay)
self.axi_set_cmda_odelay(cmda_odelay)
def axi_set_dqs_odelay_nominal(self):
"""
Set DQS output delays to nominal values (parameter-defined)
"""
self.x393_axi_tasks.write_contol_register(self.LD_DLY_LANE0_ODELAY + 8, (self.DLY_LANE0_ODELAY >> (8<<3)) & 0xff) # 32'hff);
self.x393_axi_tasks.write_contol_register(self.LD_DLY_LANE1_ODELAY + 8, (self.DLY_LANE1_ODELAY >> (8<<3)) & 0xff) # 32'hff);
self.x393_axi_tasks.write_contol_register(self.DLY_SET,0);
def axi_set_dqs_idelay_nominal(self):
"""
Set DQS input delays to nominal values (parameter-defined)
"""
self.x393_axi_tasks.write_contol_register(self.LD_DLY_LANE0_IDELAY + 8, (self.DLY_LANE0_IDELAY >> (8<<3)) & 0xff) # 32'hff);
self.x393_axi_tasks.write_contol_register(self.LD_DLY_LANE1_IDELAY + 8, (self.DLY_LANE1_IDELAY >> (8<<3)) & 0xff) # 32'hff);
self.x393_axi_tasks.write_contol_register(self.DLY_SET,0);
def axi_set_dqs_idelay_wlv(self):
"""
Set DQS input delays to values defined for the write levelling mode (parameter-defined)
"""
self.x393_axi_tasks.write_contol_register(self.LD_DLY_LANE0_IDELAY + 8, self.DLY_LANE0_DQS_WLV_IDELAY)
self.x393_axi_tasks.write_contol_register(self.LD_DLY_LANE1_IDELAY + 8, self.DLY_LANE1_DQS_WLV_IDELAY)
self.x393_axi_tasks.write_contol_register(self.DLY_SET,0)
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE0_IDELAY, 8, 1, vrlg.DLY_LANE0_DQS_WLV_IDELAY, "DLY_LANE0_IDELAY")
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE1_IDELAY, 8, 1, vrlg.DLY_LANE1_DQS_WLV_IDELAY, "DLY_LANE1_IDELAY")
# self.x393_axi_tasks.write_contol_register(vrlg.LD_DLY_LANE0_IDELAY + 8, vrlg.DLY_LANE0_DQS_WLV_IDELAY)
# self.x393_axi_tasks.write_contol_register(vrlg.LD_DLY_LANE1_IDELAY + 8, vrlg.DLY_LANE1_DQS_WLV_IDELAY)
self.x393_axi_tasks.write_contol_register(vrlg.DLY_SET,0)
def axi_set_delays(self): # set all individual delays
"""
Set all DDR3 I/O delays to individual parameter-defined values
"""
for i in range(0,10): # (i=0;i<10;i=i+1) begin
self.x393_axi_tasks.write_contol_register(self.LD_DLY_LANE0_ODELAY + i, (self.DLY_LANE0_ODELAY >> (i<<3)) & 0xff) # 32'hff);
for i in range(0,9): # (i=0;i<9;i=i+1) begin
self.x393_axi_tasks.write_contol_register(self.LD_DLY_LANE0_IDELAY + i, (self.DLY_LANE0_IDELAY >> (i<<3)) & 0xff) # 32'hff);
for i in range(0,10): # (i=0;i<10;i=i+1) begin
self.x393_axi_tasks.write_contol_register(self.LD_DLY_LANE1_ODELAY + i, (self.DLY_LANE1_ODELAY >> (i<<3)) & 0xff) # 32'hff);
for i in range(0,9): # (i=0;i<9;i=i+1) begin
self.x393_axi_tasks.write_contol_register(self.LD_DLY_LANE1_IDELAY + i, (self.DLY_LANE1_IDELAY >> (i<<3)) & 0xff) # 32'hff);
for i in range(0,32): # (i=0;i<32;i=i+1) begin
self.x393_axi_tasks.write_contol_register(self.LD_DLY_CMDA + i, (self.DLY_CMDA >> (i<<3)) & 0xff) # 32'hff);
self.x393_axi_tasks.axi_set_phase(self.DLY_PHASE); # also sets all delays
Set all DDR3 I/O delays to individual parameter-defined values (using default values,
current ones are supposed to be synchronized)
"""
self.axi_set_dq_idelay()
self.axi_set_dqs_idelay()
self.axi_set_dq_odelay()
self.axi_set_dqs_odelay()
self.axi_set_dqm_odelay()
self.axi_set_cmda_odelay()
self.axi_set_phase()
def axi_set_dq_idelay(self, # sets same delay to all dq idelay
delay): # input [7:0] delay;
delay=None): # input [7:0] delay;
"""
Set all DQ input delays to the same value
<delay> 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
Each of the two elements in the delay tuple/list may be a a common integer or a list/tuple itself
if delay is None will restore default values
"""
# print("====axi_set_dq_idelay %s"%str(delay))
if delay is None: return # Do nothing, that's OK
if isinstance(delay,int):
if delay is None:
delay=[[],[]]
for i in range(8):
delay[0].append(vrlg.get_default_field("DLY_LANE0_IDELAY",i))
delay[1].append(vrlg.get_default_field("DLY_LANE1_IDELAY",i))
if isinstance(delay,(int,long)):
delay=(delay,delay)
if self.DEBUG_MODE > 1:
print("SET DQ IDELAY="+hexMultiple(delay)) # hexMultiple
self.axi_set_multiple_delays(self.LD_DLY_LANE0_IDELAY, 8, delay[0])
self.axi_set_multiple_delays(self.LD_DLY_LANE1_IDELAY, 8, delay[1])
self.x393_axi_tasks.write_contol_register (self.DLY_SET,0);# // set all delays
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE0_IDELAY, 0, 8, delay[0], "DLY_LANE0_IDELAY")
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE1_IDELAY, 0, 8, delay[1], "DLY_LANE1_IDELAY")
self.x393_axi_tasks.write_contol_register (vrlg.DLY_SET,0);# // set all delays
def axi_set_dq_odelay(self,
delay): # input [7:0] delay;
delay=None): # input [7:0] delay;
"""
Set all DQ OUTput delays to the same value
<delay> 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
Each of the two elements in the delay tuple/list may be a a common integer or a list/tuple itself
"""
if delay is None: return # Do nothing, that's OK
if isinstance(delay,int):
if delay is None will restore default values
"""
if delay is None:
delay=[[],[]]
for i in range(8):
delay[0].append(vrlg.get_default_field("DLY_LANE0_ODELAY",i))
delay[1].append(vrlg.get_default_field("DLY_LANE1_ODELAY",i))
if isinstance(delay,(int,long)):
delay=(delay,delay)
if self.DEBUG_MODE > 1:
print("SET DQ ODELAY="+hexMultiple(delay)) # hexMultiple
self.axi_set_multiple_delays(self.LD_DLY_LANE0_ODELAY, 8, delay[0]);
self.axi_set_multiple_delays(self.LD_DLY_LANE1_ODELAY, 8, delay[1]);
self.x393_axi_tasks.write_contol_register(self.DLY_SET,0); # set all delays
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE0_ODELAY, 0, 8, delay[0], "DLY_LANE0_ODELAY");
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE1_ODELAY, 0, 8, delay[1], "DLY_LANE1_ODELAY");
self.x393_axi_tasks.write_contol_register(vrlg.DLY_SET,0); # set all delays
def axi_set_dqs_idelay(self,
delay): # input [7:0] delay;
delay=None): # input [7:0] delay;
"""
Set all DQs input delays to the same value
<delay> 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
if delay is None will restore default values
"""
if delay is None: return # Do nothing, that's OK
if isinstance(delay,int):
if delay is None:
delay=(vrlg.get_default_field("DLY_LANE0_IDELAY",8),vrlg.get_default_field("DLY_LANE1_IDELAY",8))
if isinstance(delay,(int,long)):
delay=(delay,delay)
if self.DEBUG_MODE > 1:
print("SET DQS IDELAY="+hexMultiple(delay)) # hexMultiple
self.axi_set_multiple_delays(self.LD_DLY_LANE0_IDELAY + 8, 1, delay[0])
self.axi_set_multiple_delays(self.LD_DLY_LANE1_IDELAY + 8, 1, delay[1])
self.x393_axi_tasks.write_contol_register(self.DLY_SET,0); # set all delays
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE0_IDELAY, 8, 1, delay[0], "DLY_LANE0_IDELAY")
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE1_IDELAY, 8, 1, delay[1], "DLY_LANE1_IDELAY")
self.x393_axi_tasks.write_contol_register(vrlg.DLY_SET,0); # set all delays
def axi_set_dqs_odelay(self,
delay): # input [7:0] delay;
delay=None): # input [7:0] delay;
"""
Set all DQs OUTput delays to the same value
<delay> 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
if delay is None will restore default values
"""
if delay is None: return # Do nothing, that's OK
if isinstance(delay,int):
if delay is None:
delay=(vrlg.get_default_field("DLY_LANE0_ODELAY",8),vrlg.get_default_field("DLY_LANE1_ODELAY",8))
if isinstance(delay,(int,long)):
delay=(delay,delay)
if self.DEBUG_MODE > 1:
print("SET DQS ODELAY="+hexMultiple(delay)) # hexMultiple
self.axi_set_multiple_delays(self.LD_DLY_LANE0_ODELAY + 8, 1, delay[0])
self.axi_set_multiple_delays(self.LD_DLY_LANE1_ODELAY + 8, 1, delay[1])
self.x393_axi_tasks.write_contol_register(self.DLY_SET,0); # set all delays
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE0_ODELAY, 8, 1, delay[0], "DLY_LANE0_ODELAY")
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE1_ODELAY, 8, 1, delay[1], "DLY_LANE1_ODELAY")
self.x393_axi_tasks.write_contol_register(vrlg.DLY_SET,0); # set all delays
def axi_set_dm_odelay (self,
delay): # input [7:0] delay;
delay=None): # input [7:0] delay;
"""
Set all DM output delays to the same value
<delay> 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
if delay is None will restore default values
"""
if delay is None: return # Do nothing, that's OK
if isinstance(delay,int):
if delay is None:
delay=(vrlg.get_default_field("DLY_LANE0_ODELAY",9),vrlg.get_default_field("DLY_LANE1_ODELAY",9))
if isinstance(delay,(int,long)):
delay=(delay,delay)
if self.DEBUG_MODE > 1:
print("SET DQM IDELAY="+hexMultiple(delay)) # hexMultiple
self.axi_set_multiple_delays(self.LD_DLY_LANE0_ODELAY + 9, 1, delay[0])
self.axi_set_multiple_delays(self.LD_DLY_LANE1_ODELAY + 9, 1, delay[1])
self.x393_axi_tasks.write_contol_register(self.DLY_SET,0) # set all delays
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE0_ODELAY, 9, 1, delay[0], "DLY_LANE0_ODELAY")
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE1_ODELAY, 9, 1, delay[1], "DLY_LANE1_ODELAY")
self.x393_axi_tasks.write_contol_register(vrlg.DLY_SET,0) # set all delays
def axi_set_cmda_odelay(self,
delay): # input [7:0] delay;
delay=None): # input [7:0] delay;
"""
Set all command/address output delays to the same value (or a list/tuple of the individual ones)
<delay> 8-bit (5+3) delay value to use or list/tuple containing individual values
List elements may be None, those values will not be overwritten
if delay is None will restore default values
"""
if delay is None: return # Do nothing, that's OK
if isinstance(delay,int):
if delay is None:
delay=[]
for i in range(0,32):
delay.append(vrlg.get_default_field("LD_DLY_CMDA",i))
if isinstance(delay,(int,long)):
delay=(delay,)*32 # all address/commands
if self.DEBUG_MODE > 1:
print("SET COMMAND and ADDRESS ODELAY"+hexMultiple(delay))
self.axi_set_multiple_delays(self.LD_DLY_CMDA, 32, delay);
self.x393_axi_tasks.write_contol_register(self.DLY_SET,0) # set all delays
self.axi_set_multiple_delays(vrlg.LD_DLY_CMDA, 0, 32, delay, "DLY_CMDA");
self.x393_axi_tasks.write_contol_register(vrlg.DLY_SET,0) # set all delays
def axi_set_address_odelay(self,
delay): # input [7:0] delay;
delay=None): # input [7:0] delay;
"""
Set output delays for address lines only
<delay> 8-bit (5+3) delay value to use or list/tuple containing individual values
List elements may be None, those values will not be overwritten
"""
if delay is None: return # Do nothing, that's OK
if isinstance(delay,int):
delay=(delay,)*self.ADDRESS_NUMBER
if delay is None will restore default values
"""
if delay is None:
delay=[]
for i in range(0,vrlg.ADDRESS_NUMBER):
delay.append(vrlg.get_default_field("LD_DLY_CMDA",i))
if isinstance(delay,(int,long)):
delay=(delay,)*vrlg.ADDRESS_NUMBER
if self.DEBUG_MODE > 1:
print("SET ADDRESS ODELAY="+hexMultiple(delay))
self.axi_set_multiple_delays(self.LD_DLY_CMDA, 0,delay) # 32, delay); length will be determined by len(delay)
self.x393_axi_tasks.write_contol_register(self.DLY_SET,0) # set all delays
self.axi_set_multiple_delays(vrlg.LD_DLY_CMDA, 0, 0, delay, "DLY_CMDA")
self.x393_axi_tasks.write_contol_register(vrlg.DLY_SET,0) # set all delays
def axi_set_bank_odelay(self,
delay): # input [7:0] delay;
delay=None): # input [7:0] delay;
"""
Set output delays for bank lines only
<delay> 8-bit (5+3) delay value to use or list/tuple containing individual values
List elements may be None, those values will not be overwritten
if delay is None will restore default values
"""
bank_offset=24
if delay is None: return # Do nothing, that's OK
if isinstance(delay,int):
if delay is None:
delay=[]
for i in range(3):
delay.append(vrlg.get_default_field("LD_DLY_CMDA",i+bank_offset))
if isinstance(delay,(int,long)):
delay=(delay,)*3
if self.DEBUG_MODE > 1:
print("SET BANK ODELAY="+hexMultiple(delay))
self.axi_set_multiple_delays(self.LD_DLY_CMDA+bank_offset, 0,delay) # length will be determined by len(delay)
self.x393_axi_tasks.write_contol_register(self.DLY_SET,0) # set all delays
self.axi_set_multiple_delays(vrlg.LD_DLY_CMDA, bank_offset, 0,delay, "DLY_CMDA") # length will be determined by len(delay)
self.x393_axi_tasks.write_contol_register(vrlg.DLY_SET,0) # set all delays
def axi_set_cmd_odelay(self,
delay): # input [7:0] delay;
delay=None): # input [7:0] delay;
"""
Set output delays for command lines only. command=(we,ras,cas,cke,odt)
<delay> 8-bit (5+3) delay value to use or list/tuple containing individual values
List elements may be None, those values will not be overwritten
if delay is None will restore default values
"""
command_offset=24+3
if delay is None: return # Do nothing, that's OK
if isinstance(delay,int):
delay=(delay,)*3
if delay is None:
delay=[]
for i in range(5):
delay.append(vrlg.get_default_field("LD_DLY_CMDA",i+command_offset))
if isinstance(delay,(int,long)):
delay=(delay,)*5
if self.DEBUG_MODE > 1:
print("SET COMMAND ODELAY="+hexMultiple(delay))
self.axi_set_multiple_delays(self.LD_DLY_CMDA+command_offset, 0,delay) # length will be determined by len(delay)
self.x393_axi_tasks.write_contol_register(self.DLY_SET,0) # set all delays
self.axi_set_multiple_delays(vrlg.LD_DLY_CMDA, command_offset, 0,delay, "DLY_CMDA") # length will be determined by len(delay)
self.x393_axi_tasks.write_contol_register(vrlg.DLY_SET,0) # set all delays
def axi_set_multiple_delays(self,
reg_addr, #input [29:0] reg_addr;
offset, # add this offset to address
number, # input integer number;
delay): # input [7:0] delay;
delay, # input [7:0] delay;
vname): # Verilog parameter name (if None - do not update Verilog parameter value (it is already it)
"""
Set same delay to a range of I/O delay registers
<reg_addr> control register address of the first register in the range
<offset> add this offset to address
<number> number of registers to write
<delay> 8-bit (5+3) delay value to use or list/tuple containing individual values
List elements may be None, those values will not be overwritten
<vname> Verilog parameter name
"""
# print ("===axi_set_multiple_delays(0x%x,%d,%s"%(reg_addr,number,delay))
if delay is None: return # Do nothing, that's OK
if isinstance(delay,int):
if isinstance(delay,(int,long)):
delay=(delay,)*number
if len(delay) < number:
delay= delay + (None,)*(number-len(delay)) #
for i, d in enumerate(delay):
if not d is None:
self.x393_axi_tasks.write_contol_register(reg_addr + i, d) # {24'b0,delay}); // control register address
self.x393_axi_tasks.write_contol_register(reg_addr + (offset + i), d)
if vname:
vrlg.set_name_field(vname, offset + i, d)
def wait_phase_shifter_ready(self):
"""
Wait until clock phase shifter is ready
"""
data=self.x393_axi_tasks.read_status(self.MCONTR_PHY_STATUS_REG_ADDR)
while (((data & self.STATUS_PSHIFTER_RDY_MASK) == 0) or (((data ^ self.target_phase) & 0xff) != 0)):
data=self.x393_axi_tasks.read_status(self.MCONTR_PHY_STATUS_REG_ADDR)
data=self.x393_axi_tasks.read_status(vrlg.MCONTR_PHY_STATUS_REG_ADDR)
while (((data & vrlg.STATUS_PSHIFTER_RDY_MASK) == 0) or (((data ^ vrlg.DLY_PHASE) & 0xff) != 0)):
data=self.x393_axi_tasks.read_status(vrlg.MCONTR_PHY_STATUS_REG_ADDR)
if self.DRY_MODE: break
def axi_set_wbuf_delay(self,
......@@ -347,10 +375,15 @@ class X393McntrlTiming(object):
"""
Set write to buffer latency
<delay> 4-bit write to buffer signal delay (in mclk clock cycles)
if delay is None will restore default values
"""
if delay is None:
delay= vrlg.get_default("DFLT_WBUF_DELAY")
vrlg.DFLT_WBUF_DELAY=delay
if self.DEBUG_MODE > 1:
print("SET WBUF DELAY=0x%x"%delay)
self.x393_axi_tasks.write_contol_register(self.MCONTR_PHY_16BIT_ADDR+self.MCONTR_PHY_16BIT_WBUF_DELAY, delay & 0xf) # {28'h0, delay});
self.x393_axi_tasks.write_contol_register(vrlg.MCONTR_PHY_16BIT_ADDR+vrlg.MCONTR_PHY_16BIT_WBUF_DELAY, delay & 0xf) # {28'h0, delay});
#set dq /dqs tristate on/off patterns
def axi_set_tristate_patterns(self,
......@@ -374,10 +407,10 @@ class X393McntrlTiming(object):
if not strPattern:
delays=concat(((0,16), # {16'h0,
(self.DQSTRI_LAST, getParWidth(self.DQSTRI_LAST__TYPE)), # DQSTRI_LAST,
(self.DQSTRI_FIRST,getParWidth(self.DQSTRI_FIRST__TYPE)), # DQSTRI_FIRST,
(self.DQTRI_LAST, getParWidth(self.DQTRI_LAST__TYPE)), # DQTRI_LAST,
(self.DQTRI_FIRST, getParWidth(self.DQTRI_FIRST__TYPE))) # DQTRI_FIRST});
(vrlg.DQSTRI_LAST, getParWidth(vrlg.DQSTRI_LAST__TYPE)), # DQSTRI_LAST,
(vrlg.DQSTRI_FIRST,getParWidth(vrlg.DQSTRI_FIRST__TYPE)), # DQSTRI_FIRST,
(vrlg.DQTRI_LAST, getParWidth(vrlg.DQTRI_LAST__TYPE)), # DQTRI_LAST,
(vrlg.DQTRI_FIRST, getParWidth(vrlg.DQTRI_FIRST__TYPE))) # DQTRI_FIRST});
)[0]
else:
strPattern=strPattern.upper()
......@@ -398,25 +431,19 @@ class X393McntrlTiming(object):
Exception(msg)
print ("axi_set_tristate_patterns(%s) : %s"%(strPattern,str(vals)))
delays=concat(((0,16), # {16'h0,
(vals['DQS_LAST'],4), # self.DQSTRI_LAST, getParWidth(self.DQSTRI_LAST__TYPE)), # DQSTRI_LAST,
(vals['DQS_FIRST'],4), # self.DQSTRI_FIRST,getParWidth(self.DQSTRI_FIRST__TYPE)), # DQSTRI_FIRST,
(vals['DQ_LAST'],4), # self.DQTRI_LAST, getParWidth(self.DQTRI_LAST__TYPE)), # DQTRI_LAST,
(vals['DQ_FIRST'],4)) # self.DQTRI_FIRST, getParWidth(self.DQTRI_FIRST__TYPE))) # DQTRI_FIRST});
(vals['DQS_LAST'],4), # vrlg.DQSTRI_LAST, getParWidth(vrlg.DQSTRI_LAST__TYPE)), # DQSTRI_LAST,
(vals['DQS_FIRST'],4), # vrlg.DQSTRI_FIRST,getParWidth(vrlg.DQSTRI_FIRST__TYPE)), # DQSTRI_FIRST,
(vals['DQ_LAST'],4), # vrlg.DQTRI_LAST, getParWidth(vrlg.DQTRI_LAST__TYPE)), # DQTRI_LAST,
(vals['DQ_FIRST'],4)) # vrlg.DQTRI_FIRST, getParWidth(vrlg.DQTRI_FIRST__TYPE))) # DQTRI_FIRST});
)[0]
# may fail if some of the parameters used have undefined width
print("DQTRI_FIRST=%s, DQTRI_FIRST__TYPE=%s"%(str(self.DQTRI_FIRST),str(self.DQTRI_FIRST__TYPE)))
print("DQTRI_LAST=%s, DQTRI_LAST__TYPE=%s"%(str(self.DQTRI_LAST),str(self.DQTRI_LAST__TYPE)))
# delays=concat(((0,16), # {16'h0,
# (self.DQSTRI_LAST, getParWidth(self.DQSTRI_LAST__TYPE)), # DQSTRI_LAST,
# (self.DQSTRI_FIRST,getParWidth(self.DQSTRI_FIRST__TYPE)), # DQSTRI_FIRST,
# (self.DQTRI_LAST, getParWidth(self.DQTRI_LAST__TYPE)), # DQTRI_LAST,
# (self.DQTRI_FIRST, getParWidth(self.DQTRI_FIRST__TYPE))) # DQTRI_FIRST});
# )[0]
print("DQTRI_FIRST=%s, DQTRI_FIRST__TYPE=%s"%(str(vrlg.DQTRI_FIRST),str(vrlg.DQTRI_FIRST__TYPE)))
print("DQTRI_LAST=%s, DQTRI_LAST__TYPE=%s"%(str(vrlg.DQTRI_LAST),str(vrlg.DQTRI_LAST__TYPE)))
if self.DEBUG_MODE > 1:
print("SET TRISTATE PATTERNS, combined delays=%s"%str(delays))
print("SET TRISTATE PATTERNS, combined delays=0x%x"%delays)
self.x393_axi_tasks.write_contol_register(self.MCONTR_PHY_16BIT_ADDR +self.MCONTR_PHY_16BIT_PATTERNS_TRI, delays) # DQSTRI_LAST, DQSTRI_FIRST, DQTRI_LAST, DQTRI_FIRST});
self.x393_axi_tasks.write_contol_register(vrlg.MCONTR_PHY_16BIT_ADDR +vrlg.MCONTR_PHY_16BIT_PATTERNS_TRI, delays) # DQSTRI_LAST, DQSTRI_FIRST, DQTRI_LAST, DQTRI_FIRST});
def axi_set_dqs_dqm_patterns(self,
patt=None):
......@@ -425,8 +452,16 @@ class X393McntrlTiming(object):
<patt> DQS toggle pattern (if None - use MCONTR_PHY_16BIT_PATTERNS (currently 0x55)
"""
if patt is None:
patt=self.MCONTR_PHY_16BIT_PATTERNS
patt=vrlg.MCONTR_PHY_16BIT_PATTERNS
if self.DEBUG_MODE > 1:
print("SET DQS+DQM PATTERNS, patt= 0x%x"%patt)
# set patterns for DM (always 0) and DQS - always the same (may try different for write lev.)
self.x393_axi_tasks.write_contol_register(self.MCONTR_PHY_16BIT_ADDR + self.MCONTR_PHY_16BIT_PATTERNS, patt) # 32'h0055);
self.x393_axi_tasks.write_contol_register(vrlg.MCONTR_PHY_16BIT_ADDR + vrlg.MCONTR_PHY_16BIT_PATTERNS, patt) # 32'h0055);
def util_test4(self):
# print("vrlg.globals():")
# print(vrlg.globals())
# print("vrlg.__dict__")
# print(vrlg.__dict__)
print ("DLY_PHASE = 0x%x"%vrlg.DLY_PHASE)
for k,v in vrlg.__dict__.items():
print ("%s = %s"%(k,str(v)))
......@@ -31,7 +31,6 @@ __status__ = "Development"
import mmap
#import sys
import struct
class X393Mem(object):
'''
classdocs
......
......@@ -31,13 +31,14 @@ __status__ = "Development"
#import sys
#import x393_mem
#x393_pio_sequences
from import_verilog_parameters import VerilogParameters
#from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem
from x393_axi_control_status import X393AxiControlStatus
from x393_mcntrl_buffers import X393McntrlBuffers
#from verilog_utils import * # concat, bits
from verilog_utils import concat, bits
#from x393_axi_control_status import concat, bits
import vrlg # global parameters
class X393PIOSequences(object):
DRY_MODE= True # True
DEBUG_MODE=1
......@@ -48,19 +49,10 @@ class X393PIOSequences(object):
def __init__(self, debug_mode=1,dry_mode=True):
self.DEBUG_MODE=debug_mode
self.DRY_MODE=dry_mode
# self.vpars=VerilogParameters()
self.x393_mem=X393Mem(debug_mode,dry_mode)
self.x393_axi_tasks=X393AxiControlStatus(debug_mode,dry_mode)
self.x393_mcntrl_buffers= X393McntrlBuffers(debug_mode,dry_mode)
# print ("+++++++++++++++ self.__dict__ ++++++++++++++++++++++++++")
# print (self.__dict__)
# print ("+++++++++++++++ VerilogParameters.__dict__ ++++++++++++++++++++++++++")
# print (VerilogParameters.__dict__)
# self.__dict__.update(VerilogParameters.__dict__) # Add verilog parameters to the class namespace
self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
# print ("+++++++++++++++ self.__dict__ ++++++++++++++++++++++++++")
# print (self.__dict__)
# self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
'''
Maybe import parameters into the module, not class namespace to use directly, w/o self. ?
# __dict__.update(VerilogParameters.__dict__) # Add verilog parameters to the class namespace
......@@ -81,7 +73,7 @@ class X393PIOSequences(object):
<chn> sub-channel to use: 0 - memory read, 1 - memory write
<wait_complete> Do not request a new transaction from the scheduler until previous memory transaction is finished
"""
self.x393_axi_tasks.write_contol_register(self.MCNTRL_PS_ADDR + self.MCNTRL_PS_CMD,
self.x393_axi_tasks.write_contol_register(vrlg.MCNTRL_PS_ADDR + vrlg.MCNTRL_PS_CMD,
# {17'b0,
((0,1)[wait_complete]<<14) |
((0,1)[chn]<<13) |
......@@ -100,11 +92,11 @@ class X393PIOSequences(object):
"""
self.x393_axi_tasks.wait_status_condition (
self.MCNTRL_PS_STATUS_REG_ADDR,
self.MCNTRL_PS_ADDR + self.MCNTRL_PS_STATUS_CNTRL,
vrlg.MCNTRL_PS_STATUS_REG_ADDR,
vrlg.MCNTRL_PS_ADDR + vrlg.MCNTRL_PS_STATUS_CNTRL,
mode & 3,
0,
2 << self.STATUS_2LSB_SHFT,
2 << vrlg.STATUS_2LSB_SHFT,
0,
sync_seq)
......@@ -118,11 +110,11 @@ class X393PIOSequences(object):
<synq_seq> status sequence number - see 'help program_status'
"""
self.x393_axi_tasks.wait_status_condition (
self.MCNTRL_PS_STATUS_REG_ADDR,
self.MCNTRL_PS_ADDR + self.MCNTRL_PS_STATUS_CNTRL,
vrlg.MCNTRL_PS_STATUS_REG_ADDR,
vrlg.MCNTRL_PS_ADDR + vrlg.MCNTRL_PS_STATUS_CNTRL,
mode & 3,
0,
3 << self.STATUS_2LSB_SHFT,
3 << vrlg.STATUS_2LSB_SHFT,
0,
sync_seq,
timeout)
......@@ -209,8 +201,8 @@ class X393PIOSequences(object):
<buf_rst> reset external buffer page address to 0, increment page number
"""
return self.func_encode_cmd (
((0,1)[done] << self.CMD_PAUSE_BITS) | # {{14-CMD_DONE_BIT{1'b0}}, done,
(skip & ((1 << self.CMD_PAUSE_BITS)-1)), # skip[CMD_PAUSE_BITS-1:0]}, // 15-bit row/column address
((0,1)[done] << vrlg.CMD_PAUSE_BITS) | # {{14-CMD_DONE_BIT{1'b0}}, done,
(skip & ((1 << vrlg.CMD_PAUSE_BITS)-1)), # skip[CMD_PAUSE_BITS-1:0]}, // 15-bit row/column address
bank & 7, # bank[2:0], // bank (here OK to be any)
0, # 3'b0, // RAS/CAS/WE, positive logic
odt_en, #// enable ODT
......@@ -290,7 +282,7 @@ class X393PIOSequences(object):
return concat((
(0,3), # 3'b0,
(0,self.ADDRESS_NUMBER-13), # {ADDRESS_NUMBER-13{1'b0}},
(0,vrlg.ADDRESS_NUMBER-13), # {ADDRESS_NUMBER-13{1'b0}},
(pd,1), # pd, # MR0.12
(wr,3), # wr, # MR0.11_9
(dll_rst,1), # dll_rst, # MR0.8
......@@ -348,7 +340,7 @@ class X393PIOSequences(object):
"""
return concat (( # ddr3_mr1 = {
(1,3), # 3'h1,
(0, self.ADDRESS_NUMBER-13), # {ADDRESS_NUMBER-13{1'b0}},
(0, vrlg.ADDRESS_NUMBER-13), # {ADDRESS_NUMBER-13{1'b0}},
(qoff,1), # qoff, # MR1.12
(tdqs,1), # tdqs, # MR1.11
(0,1), # 1'b0, # MR1.10
......@@ -398,7 +390,7 @@ class X393PIOSequences(object):
"""
return concat ((
(2,3), # 3'h2,
(0, self.ADDRESS_NUMBER-11), # {ADDRESS_NUMBER-11{1'b0}},
(0, vrlg.ADDRESS_NUMBER-11), # {ADDRESS_NUMBER-11{1'b0}},
(rtt_wr,2), # rtt_wr[1:0], # MR2.10_9
(0,1), # 1'b0, # MR2.8
(srt,1), # srt, # MR2.7
......@@ -420,7 +412,7 @@ class X393PIOSequences(object):
"""
return concat((
(3,3), # 3'h3,
(0,self.ADDRESS_NUMBER-3), # {ADDRESS_NUMBER-3{1'b0}},
(0,vrlg.ADDRESS_NUMBER-3), # {ADDRESS_NUMBER-3{1'b0}},
(mpr, 1), # mpr, # MR3.2
(mpr_rf,2)))[0] # mpr_rf[1:0]}; # MR3.1_0
......@@ -436,7 +428,7 @@ class X393PIOSequences(object):
<rst> 1 - reset active, 0 - reset off
"""
self.x393_axi_tasks.write_contol_register(self.MCNTRL_PS_ADDR + self.MCNTRL_PS_EN_RST,
self.x393_axi_tasks.write_contol_register(vrlg.MCNTRL_PS_ADDR + vrlg.MCNTRL_PS_EN_RST,
((0,1)[en]<<1) | #{30'b0,en,
(1,0)[rst]) #~rst});
......@@ -454,7 +446,7 @@ class X393PIOSequences(object):
<verbose> print data being written (default: False)
"""
cmd_addr = self.MCONTR_CMD_WR_ADDR + self.READ_BLOCK_OFFSET
cmd_addr = vrlg.MCONTR_CMD_WR_ADDR + vrlg.READ_BLOCK_OFFSET
# activate
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd( ra, ba, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
......@@ -519,7 +511,7 @@ class X393PIOSequences(object):
ra, # input[14:0]ra;
ca, # input[9:0]ca;
num8=64,
extraTgl=1, #
extraTgl=0, #
verbose=0):
"""
......@@ -531,7 +523,7 @@ class X393PIOSequences(object):
<verbose> print data being written (default: False)
"""
print("===set_write_block ba=0x%x, ra=0x%x, ca=0x%x"%(ba,ra,ca))
cmd_addr = self.MCONTR_CMD_WR_ADDR + self.WRITE_BLOCK_OFFSET
cmd_addr = vrlg.MCONTR_CMD_WR_ADDR + vrlg.WRITE_BLOCK_OFFSET
# activate
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd( ra, ba, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0)
......@@ -624,7 +616,7 @@ class X393PIOSequences(object):
"""
cmd_addr = self.MCONTR_CMD_WR_ADDR + self.READ_PATTERN_OFFSET
cmd_addr = vrlg.MCONTR_CMD_WR_ADDR + vrlg.READ_PATTERN_OFFSET
mr3_norm = self.func_ddr3_mr3(
0, # 1'h0, // mpr; // MPR mode: 0 - normal, 1 - dataflow from MPR
0) # 2'h0); // [1:0] mpr_rf; // MPR read function: 2'b00: predefined pattern 0101...
......@@ -729,7 +721,7 @@ class X393PIOSequences(object):
0, # 2'h0, # ods; # output drive strength: # 2'b00 - RZQ/6 - 40 Ohm
0, # 2'h0, # [1:0] al; # additive latency: 2'b00 - disabled (AL=0)
0) # 1'b0); # dll; # 0 - DLL enabled (normal), 1 - DLL disabled
cmd_addr = self.MCONTR_CMD_WR_ADDR + self.WRITELEV_OFFSET
cmd_addr = vrlg.MCONTR_CMD_WR_ADDR + vrlg.WRITELEV_OFFSET
# Enter write leveling mode
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd(bits(mr1_wlev,(14,0)), bits(mr1_wlev,(17,15)), 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
......@@ -787,7 +779,7 @@ class X393PIOSequences(object):
<verbose> print data being written (default: False)
"""
print("SET REFRESH: tRFC=%d, tREFI=%d"%(t_rfc,t_refi))
cmd_addr = self.MCONTR_CMD_WR_ADDR + self.REFRESH_OFFSET
cmd_addr = vrlg.MCONTR_CMD_WR_ADDR + vrlg.REFRESH_OFFSET
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd( 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
......@@ -803,11 +795,11 @@ class X393PIOSequences(object):
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# write_contol_register(DLY_SET,0);
self.x393_axi_tasks.write_contol_register(self.MCONTR_TOP_16BIT_ADDR + self.MCONTR_TOP_16BIT_REFRESH_ADDRESS, self.REFRESH_OFFSET)
self.x393_axi_tasks.write_contol_register(self.MCONTR_TOP_16BIT_ADDR + self.MCONTR_TOP_16BIT_REFRESH_PERIOD, t_refi)
self.x393_axi_tasks.write_contol_register(vrlg.MCONTR_TOP_16BIT_ADDR + vrlg.MCONTR_TOP_16BIT_REFRESH_ADDRESS, vrlg.REFRESH_OFFSET)
self.x393_axi_tasks.write_contol_register(vrlg.MCONTR_TOP_16BIT_ADDR + vrlg.MCONTR_TOP_16BIT_REFRESH_PERIOD, t_refi)
# enable refresh - should it be done here?
if en_refresh:
self.x393_axi_tasks.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_TOP_0BIT_REFRESH_EN + 1, 0)
self.x393_axi_tasks.write_contol_register(vrlg.MCONTR_PHY_0BIT_ADDR + vrlg.MCONTR_TOP_0BIT_REFRESH_EN + 1, 0)
def set_mrs(self, # will also calibrate ZQ
......@@ -844,7 +836,7 @@ class X393PIOSequences(object):
mr3 = self.func_ddr3_mr3(
0, # 1'h0, # mpr; # MPR mode: 0 - normal, 1 - dataflow from MPR
0) # 2'h0); # [1:0] mpr_rf; # MPR read function: 2'b00: predefined pattern 0101...
cmd_addr = self.MCONTR_CMD_WR_ADDR + self.INITIALIZE_OFFSET;
cmd_addr = vrlg.MCONTR_CMD_WR_ADDR + vrlg.INITIALIZE_OFFSET;
if self.DEBUG_MODE > 1:
print("mr0=0x%05x"%mr0);
print("mr1=0x%05x"%mr1);
......@@ -913,12 +905,12 @@ class X393PIOSequences(object):
"""
self.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.READ_PATTERN_OFFSET, # input [9:0] seq_addr; # sequence start address
vrlg.READ_PATTERN_OFFSET, # input [9:0] seq_addr; # sequence start address
2, # input [1:0] page; # buffer page number
0, # input urgent; # high priority request (only for competion with other channels, will not pass in this FIFO)
0, # input chn; # channel buffer to use: 0 - memory read, 1 - memory write
wait_complete) # `PS_PIO_WAIT_COMPLETE ) # wait_complete; # Do not request a newe transaction from the scheduler until previous memory transaction is finished
self.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1) # wait previous memory transaction finished before changing delays (effective immediately)
self.wait_ps_pio_done(vrlg.DEFAULT_STATUS_MODE,1) # wait previous memory transaction finished before changing delays (effective immediately)
return self.x393_mcntrl_buffers.read_block_buf_chn (0, 2, num, show_rslt ) # chn=0, page=2, number of 32-bit words=num, show_rslt
def read_block(self,
......@@ -934,12 +926,12 @@ class X393PIOSequences(object):
"""
self.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.READ_BLOCK_OFFSET, # input [9:0] seq_addr; # sequence start address
vrlg.READ_BLOCK_OFFSET, # input [9:0] seq_addr; # sequence start address
3, # input [1:0] page; # buffer page number
0, # input urgent; # high priority request (only for competion with other channels, will not pass in this FIFO)
0, # input chn; # channel buffer to use: 0 - memory read, 1 - memory write
wait_complete) # wait_complete; # Do not request a newe transaction from the scheduler until previous memory transaction is finished
self.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1); # wait previous memory transaction finished before changing delays (effective immediately)
self.wait_ps_pio_done(vrlg.DEFAULT_STATUS_MODE,1); # wait previous memory transaction finished before changing delays (effective immediately)
return self.x393_mcntrl_buffers.read_block_buf_chn (0, 3, num, show_rslt ) # chn=0, page=3, number of 32-bit words=num, show_rslt
def write_block(self,
......@@ -950,10 +942,10 @@ class X393PIOSequences(object):
"""
# write_block_buf_chn; # fill block memory - already set in set_up task
self.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.WRITE_BLOCK_OFFSET, # input [9:0] seq_addr; # sequence start address
vrlg.WRITE_BLOCK_OFFSET, # input [9:0] seq_addr; # sequence start address
0, # input [1:0] page; # buffer page number
0, # input urgent; # high priority request (only for competion with other channels, will not pass in this FIFO)
1, # input chn; # channel buffer to use: 0 - memory read, 1 - memory write
wait_complete) # `PS_PIO_WAIT_COMPLETE )# wait_complete; # Do not request a newer transaction from the scheduler until previous memory transaction is finished
# temporary - for debugging:
# self.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1) # wait previous memory transaction finished before changing delays (effective immediately)
# self.wait_ps_pio_done(vrlg.DEFAULT_STATUS_MODE,1) # wait previous memory transaction finished before changing delays (effective immediately)
......@@ -29,12 +29,15 @@ __maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com"
__status__ = "Development"
from import_verilog_parameters import VerilogParameters
import os
#from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem
#from verilog_utils import hx,concat, bits
#from verilog_utils import hx
#from subprocess import call
from time import sleep
import vrlg # global parameters
DEFAULT_BITFILE="/usr/local/verilog/x393.bit"
FPGA_RST_CTRL= 0xf8000240
FPGA0_THR_CTRL=0xf8000178
......@@ -46,13 +49,15 @@ class X393Utils(object):
# vpars=None
x393_mem=None
enabled_channels=0 # currently enable channels
saveFileName=None
# verbose=1
def __init__(self, debug_mode=1,dry_mode=True):
def __init__(self, debug_mode=1,dry_mode=True,saveFileName=None):
self.DEBUG_MODE=debug_mode
self.DRY_MODE=dry_mode
if saveFileName:
self.saveFileName=saveFileName.strip()
self.x393_mem=X393Mem(debug_mode,dry_mode)
self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
# self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
def reset_get(self):
"""
Get current reset state
......@@ -70,7 +75,7 @@ class X393Utils(object):
data can also be a list/tuple of integers, then it will be applied
in sequence (0,0xe) will turn reset on, then off
"""
if isinstance(data,int):
if isinstance(data, (int,long)):
self.x393_mem.write_mem(FPGA_RST_CTRL,data)
else:
for d in data:
......@@ -173,3 +178,86 @@ class X393Utils(object):
print()
return d
def getParTmpl(self):
return ({"name":"DLY_LANE0_ODELAY", "width": 80, "decl_width":""}, # decl_width can be "[7:0]", "integer", etc
{"name":"DLY_LANE0_IDELAY", "width": 72, "decl_width":""},
{"name":"DLY_LANE1_ODELAY", "width": 80, "decl_width":""},
{"name":"DLY_LANE1_IDELAY", "width": 72, "decl_width":""},
{"name":"DLY_CMDA", "width":256, "decl_width":""},
{"name":"DLY_PHASE", "width": 8, "decl_width":""})
def localparams(self,
quiet=False):
"""
Generate verilog include file with localparam definitions for the DDR3 timing parameters
Returns definition as a string
"""
nameLen=0
declWidth=0
for p in self.getParTmpl(): #parTmpl:
nameLen=max(nameLen,len(p['name']))
declWidth=max(declWidth,len(p['decl_width']))
txt=""
for p in self.getParTmpl(): # parTmpl:
numDigits = (p["width"]+3)/4
frmt="localparam %%%ds %%%ds %3d'h%%0%dx;\n"%(declWidth,nameLen+2,p["width"],numDigits)
txt+=frmt%(p['decl_width'],p['name']+" =",vrlg.__dict__[p['name']])
if not quiet:
print (txt)
return txt
def save_defaults(self,
allPars=False):
"""
Save current parameter values to defaults (as read at start up)
<allPars> use all parameters, if false - only for the ones used in
'save' file
"""
# global parTmpl
if allPars:
vrlg.save_default()
else:
for par in self.getParTmpl(): # parTmpl:
vrlg.save_default(par['name'])
def restore_defaults(self,
allPars=False):
"""
Restore parameter values from defaults (as read at start up)
<allPars> use all parameters, if false - only for the ones used in
'save' file
"""
global parTmpl
if allPars:
vrlg.restore_default()
else:
for par in parTmpl:
vrlg.restore_default(par['name'])
def save(self,
fileName=None):
"""
Write Verilog include file with localparam definitions for the DDR3 timing parameters
Also copies the same parameter values to defaults
<fileName> - optional path to write, pre-defined name if not specified
"""
header= """/* This is a generated file with the current DDR3 memory timing parameters */
"""
self.save_defaults(False) # copy current parameters to defaults
if not fileName:
fileName=self.saveFileName
txt=self.localparams(True) #quiet
if fileName:
try:
with open(fileName, "w") as text_file:
text_file.write(header)
text_file.write(txt)
print ("Verilog parameters are written to %s"%(os.path.abspath(fileName)))
except:
print ("Failed to write to %s"%(os.path.abspath(fileName)))
else:
print(txt)
......@@ -59,6 +59,7 @@ module x393_testbench01 #(
`endif
`define DEBUG_WR_SINGLE 1
`define DEBUG_RD_DATA 1
`include "includes/x393_cur_params_sim.vh" // parameters that may need adjustment, should be before x393_localparams.vh
`include "includes/x393_localparams.vh" // SuppressThisWarning VEditor - not used
// DDR3 signals
wire SDRST;
......@@ -202,35 +203,6 @@ module x393_testbench01 #(
// integer SCANLINE_CUR_Y;
wire AXI_RD_EMPTY=NUM_WORDS_READ==NUM_WORDS_EXPECTED; //SuppressThisWarning VEditor : may be unused, just for simulation
localparam FRAME_START_ADDRESS= 'h1000; // RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
localparam FRAME_FULL_WIDTH= 'h0c0; // Padded line length (8-row increment), in 8-bursts (16 bytes)
// localparam SCANLINE_WINDOW_WH= `h079000a2; // 2592*1936: low word - 13-bit window width (0->'h4000), high word - 16-bit frame height (0->'h10000)
// localparam SCANLINE_WINDOW_WH= 'h0009000b; // 176*9: low word - 13-bit window width (0->'h4000), high word - 16-bit frame height (0->'h10000)
localparam WINDOW_WIDTH= 'h000b; //'h005b; //'h000b; // 176: 13-bit window width (0->'h4000)
localparam WINDOW_HEIGHT= 'h000a; // 9: 16-bit window height (0->'h10000)
// localparam SCANLINE_X0Y0= 'h00050003; // X0=3*16=48, Y0=5: // low word - 13-bit window left, high word - 16-bit window top
localparam WINDOW_X0= 'h5c; //'h7f; // 'h005c; // 'h7c; // 'h0003; // X0=3*16=48 - 13-bit window left
localparam WINDOW_Y0= 'h0005; // Y0=5: 16-bit window top
// localparam SCANLINE_STARTXY= 'h0; // low word - 13-bit start X (relative to window), high word - 16-bit start y (normally 0)
localparam SCANLINE_STARTX= 'h0; // 13-bit start X (relative to window), high word (normally 0)
localparam SCANLINE_STARTY= 'h0; // 16-bit start y (normally 0)
localparam [1:0] SCANLINE_EXTRA_PAGES= 0; // 0..2 - number of pages in the buffer to keep/not write // SuppressThisWarning VEditor - not used
localparam TILED_STARTX= 'h0; // 13-bit start X (relative to window), high word (normally 0)
localparam TILED_STARTY= 'h0; // 16-bit start y (normally 0)
localparam [1:0] TILED_EXTRA_PAGES= 0; // 0..2 - number of pages in the buffer to keep/not write
localparam TILED_KEEP_OPEN= 1'b1; //1'b1; // 1'b0; // Do not close banks between reads (valid only for tiles <=8 rows, needed if less than 3? rows)
localparam TILE_WIDTH= 'h04; // 6-bit tile width (1..'h40)
localparam TILE_HEIGHT= 'h08; //'h05; // 'h04; //'h06; // 6-bit tile height (1..'h40) // 4 - violation
localparam TILE_VSTEP= 'h04; // 6-bit tile vertical step, with no overlap it is equal to TILE_HEIGHT (1..'h40)
localparam TEST01_START_FRAME= 1;
localparam TEST01_NEXT_PAGE= 2;
localparam TEST01_SUSPEND= 4; // SuppressThisWarning VEditor - not used
//NUM_XFER_BITS=6
......@@ -246,7 +218,6 @@ module x393_testbench01 #(
// integer ii;
// integer SCANLINE_XFER_SIZE;
localparam TEST_INITIAL_BURST= 4; // 3;
always #(CLKIN_PERIOD/2) CLK = ~CLK;
initial begin
`ifdef IVERILOG
......
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