Commit 8961bd29 authored by Andrey Filippov's avatar Andrey Filippov

more debugging with the AHCI driver, changed memory allocation for Python tests

parent f5b1c7a6
......@@ -52,87 +52,87 @@
<link>
<name>vivado_logs/VivadoBitstream.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160227133528220.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160228005230775.log</location>
</link>
<link>
<name>vivado_logs/VivadoOpt.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160227133528220.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160228005230775.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPhys.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160227133528220.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160228005230775.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPower.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160227133528220.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160228005230775.log</location>
</link>
<link>
<name>vivado_logs/VivadoPlace.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160227133528220.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160228005230775.log</location>
</link>
<link>
<name>vivado_logs/VivadoRoute.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160227133528220.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160228005230775.log</location>
</link>
<link>
<name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160227133414136.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160228005230775.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160227133528220.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160228005230775.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160227133414136.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160228005230775.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportImplemented.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160227133528220.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160228005230775.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160227133414136.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160228005230775.log</location>
</link>
<link>
<name>vivado_state/x393_sata-opt-phys.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160227133528220.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160228005230775.dcp</location>
</link>
<link>
<name>vivado_state/x393_sata-opt-power.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160227133528220.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160228005230775.dcp</location>
</link>
<link>
<name>vivado_state/x393_sata-opt.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160227133528220.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160228005230775.dcp</location>
</link>
<link>
<name>vivado_state/x393_sata-place.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160227133528220.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160228005230775.dcp</location>
</link>
<link>
<name>vivado_state/x393_sata-route.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160227133528220.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160228005230775.dcp</location>
</link>
<link>
<name>vivado_state/x393_sata-synth.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160227133414136.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160228005230775.dcp</location>
</link>
</linkedResources>
</projectDescription>
......@@ -139,6 +139,8 @@ module ahci_ctrl_stat #(
output pxci0, // pxCI current value
input hba_reset_done, // at the end of the HBA reset, clear GHC.HR, GHC.IE
output unsolicited_en, // enable processing of cominit_got and PxERR.DIAG.W interrupts from
// this bit is reset at reset, set when PxSSTS.DET==3 or PxSCTL.DET==4
/*
*/
......@@ -187,22 +189,22 @@ module ahci_ctrl_stat #(
{32{sirq_INF}} & HBA_PORT__PxIS__INFS__MASK | // 'h4000000;
{32{sirq_OF }} & HBA_PORT__PxIS__OFS__MASK | // 'h1000000;
{32{sirq_PRC}} & HBA_PORT__PxIS__PRCS__MASK | // 'h400000;
{32{sirq_PC}} & HBA_PORT__PxIS__PCS__MASK | // 'h40;
{32{sirq_PC & unsolicited_en}} & HBA_PORT__PxIS__PCS__MASK | // 'h40;
{32{sirq_DP}} & HBA_PORT__PxIS__DPS__MASK | // 'h20;
{32{sirq_UF }} & HBA_PORT__PxIS__UFS__MASK | // 'h10;
{32{sirq_SDB}} & HBA_PORT__PxIS__SDBS__MASK | // 'h8;
{32{sirq_DS }} & HBA_PORT__PxIS__DSS__MASK | // 'h4;
{32{sirq_PS }} & HBA_PORT__PxIS__PSS__MASK | // 'h2;
{32{sirq_DHR}} & HBA_PORT__PxIS__DHRS__MASK; // 'h1;
wire [31:0] serr = {32{sirq_PC}} & HBA_PORT__PxSERR__DIAG__X__MASK | // 'h4000000;
// See if sirq_PC should also be enabled by unsolicited_en. Or not?
wire [31:0] serr = {32{sirq_PC & unsolicited_en}} & HBA_PORT__PxSERR__DIAG__X__MASK | // 'h4000000;
{32{sirq_UF }} & HBA_PORT__PxSERR__DIAG__F__MASK | // 'h2000000;
{32{serr_DT }} & HBA_PORT__PxSERR__DIAG__T__MASK | // 'h1000000;
{32{serr_DS }} & HBA_PORT__PxSERR__DIAG__S__MASK | // 'h800000;
{32{serr_DH }} & HBA_PORT__PxSERR__DIAG__H__MASK | // 'h400000;
{32{serr_DC }} & HBA_PORT__PxSERR__DIAG__C__MASK | // 'h200000;
{32{serr_DB }} & HBA_PORT__PxSERR__DIAG__B__MASK | // 'h80000;
{32{serr_DW }} & HBA_PORT__PxSERR__DIAG__W__MASK | // 'h40000;
{32{serr_DW & unsolicited_en}} & HBA_PORT__PxSERR__DIAG__W__MASK | // 'h40000;
{32{serr_DI }} & HBA_PORT__PxSERR__DIAG__I__MASK | // 'h20000;
{32{sirq_PRC}} & HBA_PORT__PxSERR__DIAG__N__MASK | // 'h10000;
// {32{sirq_IF | sirq_INF }} & HBA_PORT__PxSERR__ERR__E__MASK | // 'h800;
......@@ -276,13 +278,14 @@ module ahci_ctrl_stat #(
wire update_GHC_GHC = update_ghc || update_first[6] || update_next[6];
reg pfsm_started_r;
reg unsolicited_en_r;
assign update_busy = (update_all && (|regs_changed)) || (|updating[6:1]);
assign update_pending = | regs_changed;
assign pcmd_fre = |(HBA_PORT__PxCMD__FRE__MASK & PxCMD_r);
assign serr_diag_X = |(HBA_PORT__PxSERR__DIAG__X__MASK & PxSERR_r);
assign ssts_det = PxSSTS_r[3:0];
assign unsolicited_en = unsolicited_en_r;
// assign cirq_PRC = swr_HBA_PORT__PxSERR && |(soft_write_data & HBA_PORT__PxSERR__DIAG__N__MASK);
// assign cirq_PC = swr_HBA_PORT__PxSERR && |(soft_write_data & HBA_PORT__PxSERR__DIAG__X__MASK);
......@@ -383,8 +386,15 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000;
assign pcmd_clo = PxCMD_r[3]; // causes ahci_fis_receive:clear_bsy_drq, that in turn resets this bit
assign pcmd_st = PxCMD_r[0]; // current value
always @(posedge mclk) begin
if (mrst) unsolicited_en_r <= 0;
else if (((PxSSTS_r & HBA_PORT__PxSSTS__DET__MASK) == 3) ||
(sctl_det == 4)) unsolicited_en_r <= 1;
end
always @(posedge mclk) begin
pcmd_clear_icc_r <=pcmd_clear_icc;
pcmd_clear_icc_r <= pcmd_clear_icc;
end
always @(posedge mclk) begin // Here we do not have data written by soft, only the result (cleared). If bit is 0, it is
......
......@@ -236,6 +236,9 @@ module ahci_fsm
input ch_p, // prefetchable - only used with non-zero PRDTL or ATAPI bit set
input ch_w, // Write: system memory -> device
input ch_a, // ATAPI: 1 means device should send PIO setup FIS for ATAPI command
input unsolicited_en, // enable processing of cominit_got and PxERR.DIAG.W interrupts from
// this bit is reset at reset, set when PxSSTS.DET==3 or PxSCTL.DET==4
output reg [ 9:0] last_jump_addr // debug feature
/// input [4:0] ch_cfl, // length of the command FIS in DW, 0 means none. 0 and 1 - illegal,
// maximal is 16 (0x10)
......@@ -281,7 +284,8 @@ module ahci_fsm
reg [1:0] async_pend_r; // waiting to process cominit_got
reg async_from_st; // chnge to multi-bit if there will be more sources for async transitions
wire asynq_rq = (cominit_got && unsolicited_cominit_en) || pcmd_st_cleared;
// wire asynq_rq = (cominit_got && unsolicited_cominit_en) || pcmd_st_cleared;
wire asynq_rq = (cominit_got && unsolicited_en) || pcmd_st_cleared;
// OK to wait for some time fsm_act_busy is supposed to never hang up
wire async_ackn = !fsm_preload && async_pend_r[0] && ((fsm_actions && !update_busy && !fsm_act_busy) || fsm_transitions[0]); // OK to process async jump
// reg x_rdy_collision_pend;
......@@ -297,8 +301,8 @@ module ahci_fsm
wire conditions_ce = // copy all conditions to the register so they will not change while iterating through them
!fsm_transitions_w && !fsm_transitions[0];
reg unsolicited_cominit_en; // allow unsolicited COMINITs
wire en_cominit; // en_cominit
// reg unsolicited_cominit_en; // allow unsolicited COMINITs
// wire en_cominit; // en_cominit
assign fsm_next = (fsm_preload || (fsm_actions && !update_busy && !fsm_act_busy) || fsm_transitions[0]) && !async_pend_r[0]; // quiet if received cominit is pending
assign update_all = fsm_jump[0];
......@@ -337,7 +341,7 @@ module ahci_fsm
localparam LABEL_ST_CLEARED = 11'h008;
always @ (posedge mclk) begin
if (hba_rst) unsolicited_cominit_en <= !was_port_rst;
/// if (hba_rst) unsolicited_cominit_en <= !was_port_rst;
// else if (en_cominit || comreset_send) unsolicited_cominit_en <= en_cominit;
......@@ -467,7 +471,8 @@ module ahci_fsm
.SET_OFFLINE (set_offline), // output reg
.R_OK (send_R_OK), // output reg
.R_ERR (send_R_ERR), // output reg
.EN_COMINIT (en_cominit), // output reg
// .EN_COMINIT (en_cominit), // output reg
.EN_COMINIT (), // output reg
// FIS TRANSMIT/WAIT DONE
.FETCH_CMD (fetch_cmd), // output reg
.ATAPI_XMIT (atapi_xmit), // output reg
......
......@@ -484,6 +484,10 @@ module ahci_top#(
wire [31:0] debug_dma;
wire [31:0] debug_dma1;
wire [31:0] debug_dma_h2d;
wire unsolicited_en; // enable processing of cominit_got and PxERR.DIAG.W interrupts from
// this bit is reset at reset, set when PxSSTS.DET==3 or PxSCTL.DET==4
assign comreset_send = comreset_send0 && 0;
......@@ -673,6 +677,7 @@ module ahci_top#(
.ch_a (fsnd_ch_a), // input
/// .ch_cfl (fsnd_ch_cfl), // input[4:0]
/// .dwords_sent (data_out_dwords) // input[11:0] ????
.unsolicited_en (unsolicited_en), // input
.last_jump_addr (last_jump_addr)
);
......@@ -870,6 +875,7 @@ wire[1:0] debug_get_fis_busy_r; // output[1:0]
.pxci0_clear (pxci0_clear), // input
.pxci0 (pxci0), // output
.hba_reset_done (hba_rst_done), // input
.unsolicited_en (unsolicited_en), // output
.irq (irq) // output reg
);
......@@ -1104,6 +1110,8 @@ wire [9:0] xmit_dbg_01;
// Datascope code
//`define DATASCOPE_V2
// Datascope interface (write to memory that can be software-read)
`define DATASCOPE_FIS_DATA 1
`ifdef USE_DATASCOPE
`ifdef DATASCOPE_V2
......@@ -1256,21 +1264,9 @@ debug_dma_h2d
end
assign datascope_clk = mclk;
// assign datascope_waddr = datascope_waddr_r;
assign datascope_waddr = last_jump_addr;
// assign datascope_we = (datascope_run[0] && h2d_valid && h2d_ready) || fsnd_done|| xmit_ok || xmit_err; /// || d2h_ready ;
// assign datascope_we = (datascope_run[0] && h2d_valid && h2d_ready) || d2h_ready || datascope_link_run;
/// assign datascope_we = (datascope_run[0] && h2d_valid && h2d_ready) || datascope_incoming_run[0] || datascope_link_run;
//
assign datascope_we = &datascope_new_jump;
// assign datascope_di = {14'h3fff,fsnd_pCmdToIssue, xfer_cntr_zero, datascope_jump_cntr};
assign datascope_di = {2'h3, fsnd_pCmdToIssue, xfer_cntr_zero, 2'b0, last_jump_addr[9:0],datascope_jump_cntr};
// assign datascope_di = d2h_ready? {d2h_type,
/*
`ifdef DATASCOPE_FIS_DATA
assign datascope_waddr = datascope_waddr_r;
assign datascope_we = (datascope_run[0] && h2d_valid && h2d_ready) || datascope_incoming_run[0] || datascope_link_run;
assign datascope_di = datascope_incoming_run[0]? {d2h_type,
debug_in_link[26], // state idle
debug_in_link[4:0], // encoded state (1 cycle later)
......@@ -1297,6 +1293,26 @@ debug_dma_h2d
debug_in_link[24], // fsnd_dx_err[1], //fsnd_dx_err[2:0],
debug_in_link[23],
datascope_id[2:0], {12-ADDRESS_BITS{1'b0}}, datascope_waddr_r});
always @(posedge mclk) begin
if (fsnd_cfis_xmit) datascope_waddr_r <= DATASCOPE_CFIS_START; // start from command FIS
/// if (mrst) datascope_waddr_r <= DATASCOPE_CFIS_START;
else if (datascope_we) datascope_waddr_r <= datascope_waddr_r + 1;
end
`else
assign datascope_waddr = last_jump_addr;
assign datascope_we = &datascope_new_jump;
assign datascope_di = {2'h3, fsnd_pCmdToIssue, xfer_cntr_zero, 2'b0, last_jump_addr[9:0],datascope_jump_cntr};
`endif
// assign datascope_we = (datascope_run[0] && h2d_valid && h2d_ready) || fsnd_done|| xmit_ok || xmit_err; /// || d2h_ready ;
// assign datascope_we = (datascope_run[0] && h2d_valid && h2d_ready) || d2h_ready || datascope_link_run;
//
// assign datascope_di = {14'h3fff,fsnd_pCmdToIssue, xfer_cntr_zero, datascope_jump_cntr};
// assign datascope_di = d2h_ready? {d2h_type,
/*
*/
/*
......@@ -1366,7 +1382,8 @@ assign debug_out[7: 5] = {
h2d_data[11:0]} : // 12 bits
{{32-ADDRESS_BITS{1'b0}},datascope_waddr_r};
*/ always @(posedge mclk) begin
*/
always @(posedge mclk) begin
if (mrst) datascope_run[0] <= 0;
else if (fsnd_cfis_xmit) datascope_run[0] <= 1;
else if (h2d_valid && h2d_ready && (h2d_type == 2)) datascope_run[0] <= 0;
......@@ -1380,10 +1397,6 @@ assign debug_out[7: 5] = {
datascope_run[1] <= datascope_run[0];
/// if (fsnd_cfis_xmit) datascope_waddr_r <= DATASCOPE_CFIS_START;
/// if (mrst) datascope_waddr_r <= DATASCOPE_CFIS_START;
/// else
if (datascope_we) datascope_waddr_r <= datascope_waddr_r + 1;
if (mrst) datascope_id <= 0;
......
......@@ -45,12 +45,33 @@ SI5338_PATH_OLD = '/sys/devices/amba.0/e0004000.ps7-i2c/i2c-0/0-0070'
MEM_PATH_OLD = '/sys/devices/elphel393-mem.2/'
#new System
SI5338_PATH_NEW = '/sys/devices/soc0/amba@0/e0004000.ps7-i2c/i2c-0/0-0070'
MEM_PATH_NEW = ''
MEM_PATH_NEW = '/sys/devices/soc0/elphel393-mem@0/'
DEFAULT_BITFILE="/usr/local/verilog/x393_sata.bit"
BUFFER_ADDRESS_NAME = 'buffer_address'
BUFFER_PAGES_NAME = 'buffer_pages'
BUFFER_FLUSH_NAME = 'buffer_flush'
BUFFER_ADDRESS_NAME = 'buffer_address'
BUFFER_PAGES_NAME = 'buffer_pages'
BUFFER_H2D_ADDRESS_NAME = 'buffer_address_h2d'
BUFFER_H2D_PAGES_NAME = 'buffer_pages_h2d'
BUFFER_D2H_ADDRESS_NAME = 'buffer_address_d2h'
BUFFER_D2H_PAGES_NAME = 'buffer_pages_d2h'
BUFFER_BIDIR_ADDRESS_NAME = 'buffer_address_bidir'
BUFFER_BIDIR_PAGES_NAME = 'buffer_pages_bidir'
#BUFFER_FLUSH_NAME = 'buffer_flush'
BUFFER_FOR_CPU = 'sync_for_cpu' # add suffix
BUFFER_FOR_DEVICE = 'sync_for_device' # add suffix
BUFFER_FOR_CPU_H2D = 'sync_for_cpu_h2d'
BUFFER_FOR_DEVICE_H2D = 'sync_for_device_h2d'
BUFFER_FOR_CPU_D2H = 'sync_for_cpu_d2h'
BUFFER_FOR_DEVICE_D2H = 'sync_for_device_d2h'
BUFFER_FOR_CPU_BIDIR = 'sync_for_cpu_bidir'
BUFFER_FOR_DEVICE_BIDIR = 'sync_for_device_bidir'
FPGA_RST_CTRL= 0xf8000240
FPGA0_THR_CTRL=0xf8000178
FPGA_LOAD_BITSTREAM="/dev/xdevcfg"
......@@ -71,14 +92,24 @@ IDENTIFY_BUF = 0 # Identify receive buffer offset in DATAIN_BUFF
DATAOUT_BUFFER_OFFSET = 0x20000
DATAOUT_BUFFER_SIZE = 0x10000
SI5338_PATH = None
MEM_PATH = None
SI5338_PATH = None
MEM_PATH = None
BUFFER_ADDRESS = None # in bytes
BUFFER_LEN = None # in bytes
BUFFER_ADDRESS_H2D = None # in bytes
BUFFER_LEN_H2D = None # in bytes
BUFFER_ADDRESS = None # in bytes
BUFFER_LEN = None # in bytes
COMMAND_ADDRESS = None # start of the command buffer (to be sent to device)
DATAIN_ADDRESS = None # start of the the
DATAOUT_ADDRESS = None # start of the the
BUFFER_ADDRESS_D2H = None # in bytes
BUFFER_LEN_D2H = None # in bytes
BUFFER_ADDRESS_BIDIR = None # in bytes
BUFFER_LEN_BIDIR = None # in bytes
COMMAND_ADDRESS = None # start of the command buffer (to be sent to device)
DATAIN_ADDRESS = None # start of the the
DATAOUT_ADDRESS = None # start of the the
#DRP addresses (non-GTX)
DRP_MASK_ADDR = 0x200 # ..0x207
......@@ -121,6 +152,7 @@ class x393sata(object):
register_defines=None
def __init__(self, debug_mode=1,dry_mode=False, pcb_rev = "10389"):
global BUFFER_ADDRESS, BUFFER_LEN, COMMAND_ADDRESS, DATAIN_ADDRESS, DATAOUT_ADDRESS, SI5338_PATH, MEM_PATH
global BUFFER_ADDRESS_H2D, BUFFER_LEN_H2D, BUFFER_ADDRESS_D2H, BUFFER_LEN_D2H, BUFFER_ADDRESS_BIDIR, BUFFER_LEN_BIDIR
self.DEBUG_MODE=debug_mode
if not dry_mode:
......@@ -132,8 +164,14 @@ class x393sata(object):
self.vsc3304= x393_vsc3304(debug_mode, dry_mode, pcb_rev)
self.register_defines = registers.process_data(False)['field_defines']
if dry_mode:
BUFFER_ADDRESS=0x27900000 # 0x38100000 on new
BUFFER_LEN= 0x6400000
BUFFER_ADDRESS = 0x38100000
BUFFER_LEN = 0x06400000
BUFFER_ADDRESS_H2D = 0x38100000
BUFFER_LEN_H2D = 0x06400000
BUFFER_ADDRESS_D2H = 0x38100000
BUFFER_LEN_D2 = 0x06400000
BUFFER_ADDRESS_BIDIR = 0x38100000
BUFFER_LEN_BIDIR = 0x06400000
print ("Running in simulated mode, using hard-coded addresses:")
else:
if os.path.exists(SI5338_PATH_OLD):
......@@ -147,6 +185,7 @@ class x393sata(object):
else:
print ("Does not seem to be a known system - both %s (old) and %s (new) are not found"%(SI5338_PATH_OLD, SI5338_PATH_NEW))
return
try:
with open(MEM_PATH+BUFFER_ADDRESS_NAME) as sysfile:
BUFFER_ADDRESS=int(sysfile.read(),0)
......@@ -157,14 +196,58 @@ class x393sata(object):
print('BUFFER_ADDRESS=',BUFFER_ADDRESS)
print('BUFFER_LEN=',BUFFER_LEN)
return
COMMAND_ADDRESS = BUFFER_ADDRESS + COMMAND_BUFFER_OFFSET
DATAIN_ADDRESS = BUFFER_ADDRESS + DATAIN_BUFFER_OFFSET
DATAOUT_ADDRESS = BUFFER_ADDRESS + DATAOUT_BUFFER_OFFSET
print('BUFFER_ADDRESS=0x%x'%(BUFFER_ADDRESS))
print('BUFFER_LEN=0x%x'%(BUFFER_LEN))
print('COMMAND_ADDRESS=0x%x'%(COMMAND_ADDRESS))
print('DATAIN_ADDRESS=0x%x'%(DATAIN_ADDRESS))
print('DATAOUT_ADDRESS=0x%x'%(DATAOUT_ADDRESS))
try:
with open(MEM_PATH + BUFFER_H2D_ADDRESS_NAME) as sysfile:
BUFFER_ADDRESS_H2D=int(sysfile.read(),0)
with open(MEM_PATH+BUFFER_H2D_PAGES_NAME) as sysfile:
BUFFER_LEN_H2D=PAGE_SIZE*int(sysfile.read(),0)
except:
print("Failed to get reserved physical memory range")
print('BUFFER_ADDRESS_H2D=',BUFFER_ADDRESS_H2D)
print('BUFFER_LEN_H2D=',BUFFER_LEN_H2D)
return
try:
with open(MEM_PATH + BUFFER_D2H_ADDRESS_NAME) as sysfile:
BUFFER_ADDRESS_D2H=int(sysfile.read(),0)
with open(MEM_PATH+BUFFER_D2H_PAGES_NAME) as sysfile:
BUFFER_LEN_D2H=PAGE_SIZE*int(sysfile.read(),0)
except:
print("Failed to get reserved physical memory range")
print('BUFFER_ADDRESS_D2H=',BUFFER_ADDRESS_D2H)
print('BUFFER_LEN_D2H=',BUFFER_LEN_D2H)
return
try:
with open(MEM_PATH + BUFFER_BIDIR_ADDRESS_NAME) as sysfile:
BUFFER_ADDRESS_BIDIR=int(sysfile.read(),0)
with open(MEM_PATH+BUFFER_BIDIR_PAGES_NAME) as sysfile:
BUFFER_LEN_BIDIR=PAGE_SIZE*int(sysfile.read(),0)
except:
print("Failed to get reserved physical memory range")
print('BUFFER_ADDRESS_BIDIR=',BUFFER_ADDRESS_BIDIR)
print('BUFFER_LEN_BIDIR=',BUFFER_LEN_BIDIR)
return
# COMMAND_ADDRESS = BUFFER_ADDRESS + COMMAND_BUFFER_OFFSET
# DATAIN_ADDRESS = BUFFER_ADDRESS + DATAIN_BUFFER_OFFSET
# DATAOUT_ADDRESS = BUFFER_ADDRESS + DATAOUT_BUFFER_OFFSET
COMMAND_ADDRESS = BUFFER_ADDRESS_H2D + COMMAND_BUFFER_OFFSET
DATAIN_ADDRESS = BUFFER_ADDRESS_D2H + DATAIN_BUFFER_OFFSET
DATAOUT_ADDRESS = BUFFER_ADDRESS_H2D + DATAOUT_BUFFER_OFFSET
print('BUFFER_ADDRESS = 0x%08x'%(BUFFER_ADDRESS))
print('BUFFER_LEN = 0x%08x'%(BUFFER_LEN))
print('BUFFER_ADDRESS_H2D = 0x%08x'%(BUFFER_ADDRESS_H2D))
print('BUFFER_LEN_H2D = 0x%08x'%(BUFFER_LEN_H2D))
print('BUFFER_ADDRESS_D2H = 0x%08x'%(BUFFER_ADDRESS_D2H))
print('BUFFER_LEN_D2H = 0x%08x'%(BUFFER_LEN_D2H))
print('BUFFER_ADDRESS_BIDIR = 0x%08x'%(BUFFER_ADDRESS_BIDIR))
print('BUFFER_LEN_BIDIR = 0x%08x'%(BUFFER_LEN_BIDIR))
print('COMMAND_ADDRESS = 0x%08x'%(COMMAND_ADDRESS))
print('DATAIN_ADDRESS = 0x%08x'%(DATAIN_ADDRESS))
print('DATAOUT_ADDRESS = 0x%08x'%(DATAOUT_ADDRESS))
def reset_get(self):
"""
Get current reset state
......@@ -187,15 +270,43 @@ class x393sata(object):
else:
for d in data:
self.x393_mem.write_mem(FPGA_RST_CTRL,d)
def flush_mem(self):
def get_mem_buf_args(self, saddr=None, len=None):
#Is it really needed? Or use cache line size (32B), not PAGE_SIZE?
args=""
if (saddr is None) or (len is None):
return ""
else:
eaddr = PAGE_SIZE * ((saddr+len) // PAGE_SIZE)
if ((saddr+len) % PAGE_SIZE):
eaddr += PAGE_SIZE
saddr = PAGE_SIZE * (saddr // PAGE_SIZE)
return "%d %d"%(saddr, eaddr-saddr )
def _get_dma_dir_suffix(self, direction):
if direction.upper()[0] in "HT":
return "_h2d"
elif direction.upper()[0] in "DF":
return "_d2h"
elif direction.upper()[0] in "B":
return "_bidir"
def sync_for_cpu(self, direction, saddr=None, len=None):
with open (MEM_PATH + BUFFER_FOR_CPU + self._get_dma_dir_suffix(direction),"w") as f:
print (self.get_mem_buf_args(saddr, len),file=f)
def sync_for_device(self, direction, saddr=None, len=None):
with open (MEM_PATH + BUFFER_FOR_DEVICE + self._get_dma_dir_suffix(direction),"w") as f:
print (self.get_mem_buf_args(saddr, len),file=f)
'''
def flush_mem(self, saddr=None, len=None):
"""
Flush memory buffer
"""
with open (MEM_PATH+BUFFER_FLUSH_NAME,"w") as f:
print ("1",file=f)
# PAGE_SIZE
'''
def bitstream(self,
bitfile=None,
quiet=1):
......@@ -467,6 +578,7 @@ class x393sata(object):
"""
# Clear interrupt register
self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxIS'), 0xffffffff)
self.sync_for_cpu('H2D',COMMAND_ADDRESS, 256) # command and PRD table
# clear system memory for the command
for a in range(64):
self.x393_mem.write_mem(COMMAND_ADDRESS + 4*a, 0)
......@@ -506,9 +618,13 @@ class x393sata(object):
((4 * i + 4) << 24))
"""
self.sync_for_device('H2D',COMMAND_ADDRESS, 256) # command and PRD table
self.sync_for_device('D2H',DATAIN_ADDRESS + IDENTIFY_BUF, 512)
# Make it flush (dumb way - write each cache line (32 bytes) something?
for i in range (4096):
self.x393_mem.write_mem(COMMAND_ADDRESS + 32 * i, self.x393_mem.read_mem(COMMAND_ADDRESS + 32 * i))
# for i in range (4096):
# self.x393_mem.write_mem(COMMAND_ADDRESS + 32 * i, self.x393_mem.read_mem(COMMAND_ADDRESS + 32 * i))
# print("Running flush_mem()")
# self.flush_mem() # Did not worked, caused error
......@@ -546,7 +662,9 @@ class x393sata(object):
print("Datascope (debug) data:")
print("_=mem.mem_dump (0x%x, 0x20,4)"%(DATASCOPE_ADDR))
self.x393_mem.mem_dump (DATASCOPE_ADDR, 0x20,4)
print("Memory read data:")
self.sync_for_cpu('D2H',DATAIN_ADDRESS + IDENTIFY_BUF, 512)
print("_=mem.mem_dump (0x%x, 0x100, 2)"%(DATAIN_ADDRESS + IDENTIFY_BUF))
self.x393_mem.mem_dump (DATAIN_ADDRESS + IDENTIFY_BUF, 0x100,2)
......@@ -565,6 +683,7 @@ class x393sata(object):
# Clear interrupt register
self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxIS'), 0xffffffff)
# clear system memory for the command
self.sync_for_cpu('H2D',COMMAND_ADDRESS, 256) # command and PRD table
for a in range(64):
self.x393_mem.write_mem(COMMAND_ADDRESS + 4*a, 0)
#Setup command table in system memory
......@@ -595,9 +714,12 @@ class x393sata(object):
self.x393_mem.write_mem(MAXI1_ADDR + COMMAND_HEADER0_OFFS + (2 << 2),
(COMMAND_ADDRESS) & 0xffffffc0) # 'CTBA' - Command table base address
self.sync_for_device('H2D',COMMAND_ADDRESS, 256) # command and PRD table
self.sync_for_device('D2H',DATAIN_ADDRESS , count * 512)
# Make it flush (dumb way - write each cache line (32 bytes) something?
for i in range (4096):
self.x393_mem.write_mem(COMMAND_ADDRESS + 32 * i, self.x393_mem.read_mem(COMMAND_ADDRESS + 32 * i))
# for i in range (4096):
# self.x393_mem.write_mem(COMMAND_ADDRESS + 32 * i, self.x393_mem.read_mem(COMMAND_ADDRESS + 32 * i))
# print("Running flush_mem()")
# self.flush_mem() # Did not worked, caused error
......@@ -651,7 +773,8 @@ class x393sata(object):
print("Datascope (debug) data:")
print("_=mem.mem_dump (0x%x, 0x200,4)"%(DATASCOPE_ADDR))
self.x393_mem.mem_dump (DATASCOPE_ADDR, 0x200,4)
print("Memory read data:")
print("Memory read data:")
self.sync_for_cpu('D2H',DATAIN_ADDRESS, count * 512)
print("_=mem.mem_dump (0x%x, 0x%x, 1)"%(DATAIN_ADDRESS, count * 0x200))
self.x393_mem.mem_dump (DATAIN_ADDRESS, count * 0x200, 1)
def dd_write_dma(self, skip, count = 1, use_read_buffer = False, do_not_start = False, prd_irqs = None): #TODO: Add multi-PRD testing
......@@ -671,6 +794,7 @@ class x393sata(object):
raise ValueError ("This program supports only 24-bit LBA")
data_buf = (DATAOUT_ADDRESS, DATAIN_ADDRESS) [use_read_buffer]
# clear system memory for the command
self.sync_for_cpu('H2D',COMMAND_ADDRESS, 256) # command and PRD table
for a in range(64):
self.x393_mem.write_mem(COMMAND_ADDRESS + 4*a, 0)
#Setup command table in system memory
......@@ -701,13 +825,17 @@ class x393sata(object):
self.x393_mem.write_mem(MAXI1_ADDR + COMMAND_HEADER0_OFFS + (2 << 2),
(COMMAND_ADDRESS) & 0xffffffc0) # 'CTBA' - Command table base address
self.sync_for_device('H2D',COMMAND_ADDRESS, 256) # command and PRD table
# Make it flush (dumb way - write each cache line (32 bytes) something?
for i in range (4096):
self.x393_mem.write_mem(COMMAND_ADDRESS + 32 * i, self.x393_mem.read_mem(COMMAND_ADDRESS + 32 * i))
# for i in range (4096):
# self.x393_mem.write_mem(COMMAND_ADDRESS + 32 * i, self.x393_mem.read_mem(COMMAND_ADDRESS + 32 * i))
# print("Running flush_mem()")
# self.flush_mem() # Did not worked, caused error
#mem.write_mem(0x80000118,0x11)
self.sync_for_device('H2D',data_buf, count*512)
# Set PxCMD.ST bit (it may already be set)
self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxCMD'), 0x11) # .ST and .FRE bits (FRE is readonly 1 anyway)
# Set Command Issued
......@@ -1097,6 +1225,21 @@ for block in range (1,1024):
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status(),sata.reset_ie(),sata.err_count()
mem.mem_save('/mnt/mmc/regs_dump',0x80000000,0x3000)
def mem_save (self, filename, start_addr, length):
'''
Save physical memory content to a file
@param filename - path to a file
@param start_addr physical byte start address
@param length - number of bytes to save
_=mem.mem_dump(0x3813fff8,0x2,4)
mem.mem_save('/mnt/mmc/data/regs_dump_01',0x80000000,0x3000)
mem.mem_save('/mnt/mmc/data/mem0x3000_dump_01',0x38140000,0x13e000)
#############
......
[*]
[*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI
[*] Sat Feb 27 20:28:49 2016
[*] Sun Feb 28 07:46:33 2016
[*]
[dumpfile] "/home/andrey/git/x393_sata/simulation/tb_ahci-20160227132249405.fst"
[dumpfile_mtime] "Sat Feb 27 20:25:12 2016"
[dumpfile_size] 14933340
[dumpfile] "/home/andrey/git/x393_sata/simulation/tb_ahci-20160228004322016.fst"
[dumpfile_mtime] "Sun Feb 28 07:45:26 2016"
[dumpfile_size] 15028110
[savefile] "/home/andrey/git/x393_sata/tb_ahci_01.sav"
[timestart] 27691200
[size] 1823 1173
[timestart] 0
[size] 1823 1180
[pos] 2026 0
*-17.135801 28083334 62346574 72998842 74025406 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
*-24.135801 42028606 62346574 72998842 74025406 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] tb_ahci.
[treeopen] tb_ahci.axi_read_addr.
[treeopen] tb_ahci.dev.linkMonitorFIS.
......@@ -1493,11 +1493,89 @@ tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxCMD_r[31:0]
(31)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxCMD_r[31:0]
@1401200
-group_end
@23
@22
tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSSTS_r[11:0]
@28
tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.pcmd_clear_icc
tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.pcmd_clear_icc_r
tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.unsolicited_en
@22
tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.sirq[31:0]
tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.serr[31:0]
@c00022
tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
@28
(0)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(1)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(2)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(3)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(4)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(5)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(6)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(7)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(8)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(9)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(10)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(11)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(12)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(13)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(14)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(15)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(16)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(17)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(18)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(19)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(20)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(21)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(22)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(23)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(24)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(25)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(26)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(27)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(28)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(29)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(30)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
(31)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxSERR_r[31:0]
@1401200
-group_end
@c00022
tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
@28
(0)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(1)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(2)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(3)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(4)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(5)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(6)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(7)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(8)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(9)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(10)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(11)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(12)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(13)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(14)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(15)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(16)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(17)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(18)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(19)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(20)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(21)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(22)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(23)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(24)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(25)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(26)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(27)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(28)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(29)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(30)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
(31)tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
@1401200
-group_end
@c00200
-ssts
@c00022
......@@ -5033,8 +5111,21 @@ tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr_r[9:0]
-group_end
@28
tb_ahci.dut.sata_top.ahci_top_i.datascope_we
@22
@c00023
tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr[9:0]
@28
(0)tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr[9:0]
(1)tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr[9:0]
(2)tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr[9:0]
(3)tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr[9:0]
(4)tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr[9:0]
(5)tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr[9:0]
(6)tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr[9:0]
(7)tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr[9:0]
(8)tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr[9:0]
(9)tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr[9:0]
@1401201
-group_end
@1000200
-datascope
@c00200
......
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