Loading ahci/ahci_fsm.v +112 −24 Original line number Diff line number Diff line Loading @@ -246,12 +246,12 @@ module ahci_fsm ); `include "includes/ahci_localparams.vh" // @SuppressThisWarning VEditor : Unused localparams reg [10:0] pgm_waddr; reg [ 9:0] pgm_waddr; // wire pgm_ren; // wire pgm_regen; wire cond_met_w; // calculated from signals and program conditions decoder reg [10:0] pgm_jump_addr; reg [10:0] pgm_addr; reg [ 9:0] pgm_jump_addr; reg [ 9:0] pgm_addr; wire [17:0] pgm_data; reg was_rst; // reg jump_r; Loading @@ -261,8 +261,8 @@ module ahci_fsm reg fsm_act_busy; reg [1:0] fsm_transitions; // processing transitions reg fsm_preload; // read first sequence data (2 cycles for regen) wire [6:0] precond_w = pgm_data[17:11]; // select what to use - cond_met_w valis after precond_w, same time as conditions reg [6:0] conditions; wire [7:0] precond_w = pgm_data[17:10]; // select what to use - cond_met_w valis after precond_w, same time as conditions reg [7:0] conditions; wire pre_jump_w = (|async_pend_r) ? async_ackn : (cond_met_w & fsm_transitions[1]); wire fsm_act_done = get_fis_done || xmit_done; wire fsm_wait_act_w = pgm_data[16]; // this action requires waiting for done Loading @@ -282,7 +282,7 @@ module ahci_fsm // Writing to the FSM program memory always @ (posedge aclk) begin if (arst) pgm_waddr <= 0; else if (pgm_wa) pgm_waddr <= pgm_ad[10:0]; else if (pgm_wa) pgm_waddr <= pgm_ad[ 9:0]; else if (pgm_wd) pgm_waddr <= pgm_waddr + 1; end // Reset addresses - later use generated Loading @@ -295,7 +295,7 @@ module ahci_fsm always @ (posedge mclk) begin if (hba_rst) pgm_jump_addr <= (was_hba_rst || was_port_rst) ? (was_hba_rst? LABEL_HBA_RST:LABEL_PORT_RST) : LABEL_POR; else if (async_pend_r[1]) pgm_jump_addr <= async_from_st? LABEL_ST_CLEARED : LABEL_COMINIT; else if (fsm_transitions[0] && (!cond_met_w || !fsm_transitions[1])) pgm_jump_addr <= pgm_data[10:0]; else if (fsm_transitions[0] && (!cond_met_w || !fsm_transitions[1])) pgm_jump_addr <= pgm_data[9:0]; was_rst <= hba_rst; Loading Loading @@ -337,25 +337,11 @@ module ahci_fsm end /* sequence = [{LBL:'POR', ADR: 0x0, ACT: NOP}, { GOTO:'H:Init'}, {LBL:'HBA_RST', ADR: 0x2, ACT: NOP}, { GOTO:'H:Init'}, {LBL:'PORT_RST', ADR: 0x4, ACT: NOP}, { GOTO:'H:Init'}, {LBL:'COMINIT', ADR: 0x6, ACT: NOP}, { GOTO:'P:Cominit'}, */ ramp_var_w_var_r #( ram18p_var_w_var_r #( .REGISTERS(1), .LOG2WIDTH_WR(4), .LOG2WIDTH_RD(4) `include "includes/ahxi_fsm_code.vh" ) fsm_pgm_mem_i ( .rclk (mclk), // input .raddr (pgm_addr), // input[10:0] Loading @@ -365,10 +351,112 @@ sequence = [{LBL:'POR', ADR: 0x0, ACT: NOP}, .wclk (aclk), // input .waddr (pgm_waddr), // input[10:0] .we (pgm_wd), // input .web (8'hff), // input[7:0] .web (4'hff), // input[7:0] .data_in (pgm_ad) // input[17:0] ); action_decoder action_decoder_i ( .clk (mclk), // input .enable (), // input .data (), // input[10:0] .PXSERR_DIAG_X (), // output reg .SIRQ_DHR (), // output reg .SIRQ_DP (), // output reg .SIRQ_DS (), // output reg .SIRQ_IF (), // output reg .SIRQ_PS (), // output reg .SIRQ_SDB (), // output reg .SIRQ_TFE (), // output reg .SIRQ_UF (), // output reg .PFSM_STARTED (), // output reg .PCMD_CR_CLEAR (), // output reg .PCMD_CR_SET (), // output reg .PXCI0_CLEAR (), // output reg .PXSSTS_DET_1 (), // output reg .SSTS_DET_OFFLINE (), // output reg .SET_UPDATE_SIG (), // output reg .UPDATE_SIG (), // output reg .UPDATE_ERR_STS (), // output reg .UPDATE_PIO (), // output reg .UPDATE_PRDBC (), // output reg .CLEAR_BSY_DRQ (), // output reg .CLEAR_BSY_SET_DRQ (), // output reg .SET_BSY (), // output reg .SET_STS_7F (), // output reg .SET_STS_80 (), // output reg .XFER_CNTR_CLEAR (), // output reg .DECR_DWC (), // output reg .FIS_FIRST_FLUSH (), // output reg .CLEAR_CMD_TO_ISSUE (), // output reg .DMA_ABORT (), // output reg .DMA_PRD_IRQ_CLEAR (), // output reg .XMIT_COMRESET (), // output reg .SEND_SYNC_ESC (), // output reg .SET_OFFLINE (), // output reg .R_OK (), // output reg .R_ERR (), // output reg .FETCH_CMD (), // output reg .ATAPI_XMIT (), // output reg .CFIS_XMIT (), // output reg .DX_XMIT (), // output reg .GET_DATA_FIS (), // output reg .GET_DSFIS (), // output reg .GET_IGNORE (), // output reg .GET_PSFIS (), // output reg .GET_RFIS (), // output reg .GET_SDBFIS (), // output reg .GET_UFIS () // output reg ); condition_mux condition_mux_i ( .clk (mclk), // input .sel (), // input[7:0] .condition (), // output .ST_NB_ND (), // input .PXCI0_NOT_CMDTOISSUE (), // input .PCTI_CTBAR_XCZ (), // input .PCTI_XCZ (), // input .NST_D2HR (), // input .NPD_NCA (), // input .CHW_DMAA (), // input .SCTL_DET_CHANGED_TO_4 (), // input .SCTL_DET_CHANGED_TO_1 (), // input .PXSSTS_DET_NE_3 (), // input .PXSSTS_DET_EQ_1 (), // input .NPCMD_FRE (), // input .FIS_OK (), // input .FIS_ERR (), // input .FIS_FERR (), // input .FIS_EXTRA (), // input .FIS_FIRST_INVALID (), // input .FR_D2HR (), // input .FIS_DATA (), // input .FIS_ANY (), // input .NB_ND_D2HR_PIO (), // input .D2HR (), // input .SDB (), // input .DMA_ACT (), // input .DMA_SETUP (), // input .BIST_ACT_FE (), // input .BIST_ACT (), // input .PIO_SETUP (), // input .NB_ND (), // input .TFD_STS_ERR (), // input .FIS_I (), // input .PIO_I (), // input .NPD (), // input .PIOX (), // input .XFER0 (), // input .PIOX_XFER0 (), // input .CTBAA_CTBAP (), // input .CTBAP (), // input .CTBA_B (), // input .CTBA_C (), // input .TX_ERR (), // input .SYNCESC_ERR (), // input .DMA_PRD_IRQ_PEND (), // input .X_RDY_COLLISION () // input ); /* Loading generated/action_decoder.v +48 −48 Original line number Diff line number Diff line /******************************************************************************* * Module: action_decoder * Date:2016-01-18 * Date:2016-01-19 * Author: auto-generated file, see ahci_fsm_sequence.py * Description: Decode sequencer code to 1-hot actions *******************************************************************************/ Loading Loading @@ -60,52 +60,52 @@ module action_decoder ( output reg GET_UFIS); always @(posedge clk) begin PXSERR_DIAG_X <= enable && data[ 2] && data[ 0]; SIRQ_DHR <= enable && data[ 3] && data[ 0]; SIRQ_DP <= enable && data[ 4] && data[ 0]; SIRQ_DS <= enable && data[ 5] && data[ 0]; SIRQ_IF <= enable && data[ 6] && data[ 0]; SIRQ_PS <= enable && data[ 7] && data[ 0]; SIRQ_SDB <= enable && data[ 8] && data[ 0]; SIRQ_TFE <= enable && data[ 9] && data[ 0]; SIRQ_UF <= enable && data[10] && data[ 0]; PFSM_STARTED <= enable && data[ 2] && data[ 1]; PCMD_CR_CLEAR <= enable && data[ 3] && data[ 1]; PCMD_CR_SET <= enable && data[ 4] && data[ 1]; PXCI0_CLEAR <= enable && data[ 5] && data[ 1]; PXSSTS_DET_1 <= enable && data[ 6] && data[ 1]; SSTS_DET_OFFLINE <= enable && data[ 7] && data[ 1]; SET_UPDATE_SIG <= enable && data[ 8] && data[ 1]; UPDATE_SIG <= enable && data[ 9] && data[ 1]; UPDATE_ERR_STS <= enable && data[10] && data[ 1]; UPDATE_PIO <= enable && data[ 3] && data[ 2]; UPDATE_PRDBC <= enable && data[ 4] && data[ 2]; CLEAR_BSY_DRQ <= enable && data[ 5] && data[ 2]; CLEAR_BSY_SET_DRQ <= enable && data[ 6] && data[ 2]; SET_BSY <= enable && data[ 7] && data[ 2]; SET_STS_7F <= enable && data[ 8] && data[ 2]; SET_STS_80 <= enable && data[ 9] && data[ 2]; XFER_CNTR_CLEAR <= enable && data[10] && data[ 2]; DECR_DWC <= enable && data[ 4] && data[ 3]; FIS_FIRST_FLUSH <= enable && data[ 5] && data[ 3]; CLEAR_CMD_TO_ISSUE <= enable && data[ 6] && data[ 3]; DMA_ABORT <= enable && data[ 7] && data[ 3]; DMA_PRD_IRQ_CLEAR <= enable && data[ 8] && data[ 3]; XMIT_COMRESET <= enable && data[ 9] && data[ 3]; SEND_SYNC_ESC <= enable && data[10] && data[ 3]; SET_OFFLINE <= enable && data[ 5] && data[ 4]; R_OK <= enable && data[ 6] && data[ 4]; R_ERR <= enable && data[ 7] && data[ 4]; FETCH_CMD <= enable && data[ 8] && data[ 4]; ATAPI_XMIT <= enable && data[ 9] && data[ 4]; CFIS_XMIT <= enable && data[10] && data[ 4]; DX_XMIT <= enable && data[ 6] && data[ 5]; GET_DATA_FIS <= enable && data[ 7] && data[ 5]; GET_DSFIS <= enable && data[ 8] && data[ 5]; GET_IGNORE <= enable && data[ 9] && data[ 5]; GET_PSFIS <= enable && data[10] && data[ 5]; GET_RFIS <= enable && data[ 7] && data[ 6]; GET_SDBFIS <= enable && data[ 8] && data[ 6]; GET_UFIS <= enable && data[ 9] && data[ 6]; PXSERR_DIAG_X <= enable && data[ 1] && data[ 0]; SIRQ_DHR <= enable && data[ 2] && data[ 0]; SIRQ_DP <= enable && data[ 3] && data[ 0]; SIRQ_DS <= enable && data[ 4] && data[ 0]; SIRQ_IF <= enable && data[ 5] && data[ 0]; SIRQ_PS <= enable && data[ 6] && data[ 0]; SIRQ_SDB <= enable && data[ 7] && data[ 0]; SIRQ_TFE <= enable && data[ 8] && data[ 0]; SIRQ_UF <= enable && data[ 9] && data[ 0]; PFSM_STARTED <= enable && data[10] && data[ 0]; PCMD_CR_CLEAR <= enable && data[ 2] && data[ 1]; PCMD_CR_SET <= enable && data[ 3] && data[ 1]; PXCI0_CLEAR <= enable && data[ 4] && data[ 1]; PXSSTS_DET_1 <= enable && data[ 5] && data[ 1]; SSTS_DET_OFFLINE <= enable && data[ 6] && data[ 1]; SET_UPDATE_SIG <= enable && data[ 7] && data[ 1]; UPDATE_SIG <= enable && data[ 8] && data[ 1]; UPDATE_ERR_STS <= enable && data[ 9] && data[ 1]; UPDATE_PIO <= enable && data[10] && data[ 1]; UPDATE_PRDBC <= enable && data[ 3] && data[ 2]; CLEAR_BSY_DRQ <= enable && data[ 4] && data[ 2]; CLEAR_BSY_SET_DRQ <= enable && data[ 5] && data[ 2]; SET_BSY <= enable && data[ 6] && data[ 2]; SET_STS_7F <= enable && data[ 7] && data[ 2]; SET_STS_80 <= enable && data[ 8] && data[ 2]; XFER_CNTR_CLEAR <= enable && data[ 9] && data[ 2]; DECR_DWC <= enable && data[10] && data[ 2]; FIS_FIRST_FLUSH <= enable && data[ 4] && data[ 3]; CLEAR_CMD_TO_ISSUE <= enable && data[ 5] && data[ 3]; DMA_ABORT <= enable && data[ 6] && data[ 3]; DMA_PRD_IRQ_CLEAR <= enable && data[ 7] && data[ 3]; XMIT_COMRESET <= enable && data[ 8] && data[ 3]; SEND_SYNC_ESC <= enable && data[ 9] && data[ 3]; SET_OFFLINE <= enable && data[10] && data[ 3]; R_OK <= enable && data[ 5] && data[ 4]; R_ERR <= enable && data[ 6] && data[ 4]; FETCH_CMD <= enable && data[ 7] && data[ 4]; ATAPI_XMIT <= enable && data[ 8] && data[ 4]; CFIS_XMIT <= enable && data[ 9] && data[ 4]; DX_XMIT <= enable && data[10] && data[ 4]; GET_DATA_FIS <= enable && data[ 6] && data[ 5]; GET_DSFIS <= enable && data[ 7] && data[ 5]; GET_IGNORE <= enable && data[ 8] && data[ 5]; GET_PSFIS <= enable && data[ 9] && data[ 5]; GET_RFIS <= enable && data[10] && data[ 5]; GET_SDBFIS <= enable && data[ 7] && data[ 6]; GET_UFIS <= enable && data[ 8] && data[ 6]; end endmodule generated/condition_mux.v +4 −3 Original line number Diff line number Diff line /******************************************************************************* * Module: condition_mux * Date:2016-01-18 * Date:2016-01-19 * Author: auto-generated file, see ahci_fsm_sequence.py * Description: Select condition *******************************************************************************/ Loading Loading @@ -56,7 +56,7 @@ module condition_mux ( input DMA_PRD_IRQ_PEND, input X_RDY_COLLISION); wire [43:0] masked; wire [44:0] masked; reg [ 5:0] cond_r; assign condition = |cond_r; Loading Loading @@ -105,6 +105,7 @@ module condition_mux ( assign masked[41] = SYNCESC_ERR && sel[ 6] && sel[ 4] && sel[ 2]; assign masked[42] = DMA_PRD_IRQ_PEND && sel[ 7] && sel[ 4] && sel[ 2]; assign masked[43] = X_RDY_COLLISION && sel[ 6] && sel[ 5] && sel[ 2]; assign masked[44] = !(|sel); // always TRUE condition (sel ==0) always @(posedge clk) begin cond_r[ 0] <= |masked[ 7: 0]; Loading @@ -112,6 +113,6 @@ module condition_mux ( cond_r[ 2] <= |masked[23:16]; cond_r[ 3] <= |masked[31:24]; cond_r[ 4] <= |masked[39:32]; cond_r[ 5] <= |masked[43:40]; cond_r[ 5] <= |masked[44:40]; end endmodule helpers/ahci_fsm_sequence.py +166 −6 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ action_decoder_module_name= 'action_decoder' condition_mux_verilog_path= '../generated/condition_mux.v' condition_mux_module_name= 'condition_mux' condition_mux_fanout = 8 code_rom_path= '../includes/ahxi_fsm_code.vh' #Set actions, conditions to empty string to rebuild list. Then edit order and put here actions = ['NOP', # CTRL_STAT Loading Loading @@ -477,13 +478,15 @@ module %s ( num_inputs += 1 v >>= 1 maximal_length = max([len(n) for n in conditions]) numregs = (len(conditions) + fanout - 1) // fanout # numregs = (len(conditions) + fanout - 1) // fanout numregs = (len(conditions) + fanout) // fanout # one more bit for 'always' (sel == 0) header = header_template%(module_name, datetime.date.today().isoformat(), os.path.basename(__file__), module_name, num_inputs-1) print(header,file=file) for input_name in conditions[:len(conditions)-1]: print(" input %s,"%(input_name),file=file) print(" input %s);\n"%(conditions[-1]),file=file) print(" wire [%2d:0] masked;"%(len(conditions)-1),file=file) # print(" wire [%2d:0] masked;"%(len(conditions)-1),file=file) print(" wire [%2d:0] masked;"%(len(conditions)),file=file) if numregs > 1: print(" reg [%2d:0] cond_r;\n"%(numregs-1),file=file) else: Loading @@ -502,10 +505,13 @@ module %s ( if d & (1 << nb): print (" && sel[%2d]"%(nb), end="", file=file) print (";", file=file) print(" assign masked[%2d] = !(|sel); // always TRUE condition (sel ==0)"%(len(conditions)), file=file) print ("\n always @(posedge clk) begin", file=file) for nb in range (numregs): ll = nb * fanout hl = min(ll + fanout, len(conditions)) -1 # hl = min(ll + fanout, len(conditions)) -1 hl = min(ll + fanout -1, len(conditions)) if numregs > 1: print (" cond_r[%2d] <= "%(nb), end="", file=file) else: Loading Loading @@ -562,6 +568,111 @@ module %s ( print (";", file=file) print (" end", file=file) print("endmodule",file=file) #def code_generator (sequence, actions, action_vals,conditions, condition_vals, labels): def code_generator (sequence, action_vals, condition_vals, labels): wait_act = 0x10000 last_act = 0x20000 act_mask = 0x0ffff # actually 0x007ff (11 bits) is enough goto_mask = 0x003ff # 10-bit address cond_mask = 0xff # before << cond_shift = 10 # jump_mode = False; code=[] for a, l in enumerate (sequence): # checks if not jump_mode: if (IF in l) or (GOTO in l): raise Exception ("Unexpected line %d: %s - was expecting action, not GOTO"%(a,str(l))) else: if (LBL in l) or (ACT in l) or (ADDR in l): jump_mode = False # set ACT mode before processing, set GOTO mode - after processing if IF in sequence[a-1]: # first ACT after JUMP raise Exception ("Last jump (%d: %s) should be unconditional GOTO"%(a-1,str(sequence[a-1]))) d=0 if not jump_mode: if ACT in l: act = action_vals[l[ACT]] if act != (act & act_mask): raise Exception ("ACT = 0x%x does not fit into designated field (0x%x) in line %d:%s"%(act, act_mask, a,str(l))) d=act | (0,wait_act)[l[ACT].endswith('*')] if (GOTO in sequence[a+1]): jump_mode = True d |= last_act else: # jump mode goto = labels[l[GOTO]] if goto != (goto & goto_mask): raise Exception ("GOTO = 0x%x does not fit into designated field (0x%x) in line %d:%s"%(goto, goto_mask, a,str(l))) cond = 0 if IF in l: cond = condition_vals[l[IF]] if cond != (cond & cond_mask): raise Exception ("IF = 0x%x does not fit into designated field (0x%x) in line %d:%s"%(cond, cond_mask, a,str(l))) d = goto | (cond << cond_shift) code.append(d) return code def create_with_parity (init_data, # numeric data (may be less than full array num_bits, # number of bits in item, valid: 1,2,4,8,9,16,18,32,36,64,72 # start_bit, # bit number to start filling from full_bram): # true if ramb36, false - ramb18 d = num_bits num_bits8 = 1; while d > 1: d >>= 1 num_bits8 <<= 1 bsize = (0x4000,0x8000)[full_bram] bdata = [0 for i in range(bsize)] sb = 0 for item in init_data: for bt in range (num_bits8): bdata[sb+bt] = (item >> bt) & 1; sb += num_bits8 data = [] for i in range (len(bdata)//256): d = 0; for b in range(255, -1,-1): d = (d<<1) + bdata[256*i+b] data.append(d) data_p = [] num_bits_p = num_bits8 >> 3 sb = 0 print ("num_bits=",num_bits) print ("num_bits8=",num_bits8) print ("num_bits_p=",num_bits_p) if num_bits_p: pbsize = bsize >> 3 pbdata = [0 for i in range(pbsize)] for item in init_data: # print ("item = 0x%x, p = 0x%x"%(item,item >> num_bits8)) for bt in range (num_bits_p): pbdata[sb+bt] = (item >> (bt+num_bits8)) & 1; # print ("pbdata[%d] = 0x%x"%(sb+bt, pbdata[sb+bt])) sb += num_bits_p for i in range (len(pbdata)//256): d = 0; for b in range(255, -1,-1): d = (d<<1) + pbdata[256*i+b] data_p.append(d) # print(bdata) # print(data) # print(pbdata) # print(data_p) return {'data':data,'data_p':data_p} def print_params(data,out_file_name): with open(out_file_name,"w") as out_file: for i, v in enumerate(data['data']): if v: print (", .INIT_%02X (256'h%064X)"%(i,v), file=out_file) # if (include_parity): for i, v in enumerate(data['data_p']): if v: print (", .INITP_%02X (256'h%064X)"%(i,v), file=out_file) #print (sequence) ln = 0 while ln < len(sequence): Loading Loading @@ -644,8 +755,13 @@ if sort_conditions: #Assign values to actions action_vals={} vals = bin_cnk (*actions_cnk) indx = 0 for i, v in enumerate (actions): action_vals[v]= vals[i] if v == 'NOP': action_vals[v]= 0 else: action_vals[v]= vals[indx] indx += 1 #Assign values to conditions condition_vals={} vals = bin_cnk (*conditions_cnk) Loading Loading @@ -674,8 +790,8 @@ for i,c in enumerate(conditions): # print ("%02d: %s"%(i,c)) print ("%s"%(c)) print ("action_vals=", action_vals) print ("condition_vals=",condition_vals) #print ("action_vals=", action_vals) #print ("condition_vals=",condition_vals) #for i, line in enumerate(sequence): # print ("%03x: %s"%(i,line)) Loading @@ -694,5 +810,49 @@ else: condition_mux_verilog(conditions, condition_vals,condition_mux_module_name, condition_mux_fanout, out_file) print ("AHCI FSM conditions multiplexer is written to %s"%(os.path.abspath(os.path.join(os.path.dirname(__file__), condition_mux_verilog_path)))) code = code_generator (sequence, action_vals, condition_vals, labels) #print_params(create_with_parity(code, 18, 0, False),os.path.abspath(os.path.join(os.path.dirname(__file__), code_rom_path))) print_params(create_with_parity(code, 18, False),os.path.abspath(os.path.join(os.path.dirname(__file__), code_rom_path))) print ("AHCI FSM code data is written to %s"%(os.path.abspath(os.path.join(os.path.dirname(__file__), code_rom_path)))) #longest_label = max([len(labels[l]) for l in labels.keys()]) longest_label = max([len(l) for l in labels]) longest_act = max([len(act) for act in actions]) longest_cond = max([len(cond) for cond in conditions]) format_act = "%%%ds do %%s%%s"%(longest_label+1) format_cond = "%%%ds %%%ds goto %%s"%(longest_label+1, longest_cond+3) #print ("format_act=", format_act) #print ("format_cond=",format_cond) print ("\n code:") for a,c in enumerate(code): l = sequence[a] if LBL in l: print() print ("%03x: %05x #"%(a,c),end = "") if (ACT in l) or (LBL in l): try: lbl = l[LBL]+":" except: lbl = "" try: act = l[ACT] except: act = "NOP" wait = "" if act.endswith('*'): wait = ", WAIT DONE" act = act[0:-1] print(format_act%(lbl,act,wait)) else: try: cond = "if "+l[IF] except: cond = "always" cond += ' '*(longest_cond+3-len(cond)) print(format_cond%("",cond,l[GOTO])) # print ("%03x: %05x # %s"%(a,c,str(sequence[a]))) #condition_mux_verilog(conditions, condition_vals, 'condition_mux',100, file=None) No newline at end of file Loading
ahci/ahci_fsm.v +112 −24 Original line number Diff line number Diff line Loading @@ -246,12 +246,12 @@ module ahci_fsm ); `include "includes/ahci_localparams.vh" // @SuppressThisWarning VEditor : Unused localparams reg [10:0] pgm_waddr; reg [ 9:0] pgm_waddr; // wire pgm_ren; // wire pgm_regen; wire cond_met_w; // calculated from signals and program conditions decoder reg [10:0] pgm_jump_addr; reg [10:0] pgm_addr; reg [ 9:0] pgm_jump_addr; reg [ 9:0] pgm_addr; wire [17:0] pgm_data; reg was_rst; // reg jump_r; Loading @@ -261,8 +261,8 @@ module ahci_fsm reg fsm_act_busy; reg [1:0] fsm_transitions; // processing transitions reg fsm_preload; // read first sequence data (2 cycles for regen) wire [6:0] precond_w = pgm_data[17:11]; // select what to use - cond_met_w valis after precond_w, same time as conditions reg [6:0] conditions; wire [7:0] precond_w = pgm_data[17:10]; // select what to use - cond_met_w valis after precond_w, same time as conditions reg [7:0] conditions; wire pre_jump_w = (|async_pend_r) ? async_ackn : (cond_met_w & fsm_transitions[1]); wire fsm_act_done = get_fis_done || xmit_done; wire fsm_wait_act_w = pgm_data[16]; // this action requires waiting for done Loading @@ -282,7 +282,7 @@ module ahci_fsm // Writing to the FSM program memory always @ (posedge aclk) begin if (arst) pgm_waddr <= 0; else if (pgm_wa) pgm_waddr <= pgm_ad[10:0]; else if (pgm_wa) pgm_waddr <= pgm_ad[ 9:0]; else if (pgm_wd) pgm_waddr <= pgm_waddr + 1; end // Reset addresses - later use generated Loading @@ -295,7 +295,7 @@ module ahci_fsm always @ (posedge mclk) begin if (hba_rst) pgm_jump_addr <= (was_hba_rst || was_port_rst) ? (was_hba_rst? LABEL_HBA_RST:LABEL_PORT_RST) : LABEL_POR; else if (async_pend_r[1]) pgm_jump_addr <= async_from_st? LABEL_ST_CLEARED : LABEL_COMINIT; else if (fsm_transitions[0] && (!cond_met_w || !fsm_transitions[1])) pgm_jump_addr <= pgm_data[10:0]; else if (fsm_transitions[0] && (!cond_met_w || !fsm_transitions[1])) pgm_jump_addr <= pgm_data[9:0]; was_rst <= hba_rst; Loading Loading @@ -337,25 +337,11 @@ module ahci_fsm end /* sequence = [{LBL:'POR', ADR: 0x0, ACT: NOP}, { GOTO:'H:Init'}, {LBL:'HBA_RST', ADR: 0x2, ACT: NOP}, { GOTO:'H:Init'}, {LBL:'PORT_RST', ADR: 0x4, ACT: NOP}, { GOTO:'H:Init'}, {LBL:'COMINIT', ADR: 0x6, ACT: NOP}, { GOTO:'P:Cominit'}, */ ramp_var_w_var_r #( ram18p_var_w_var_r #( .REGISTERS(1), .LOG2WIDTH_WR(4), .LOG2WIDTH_RD(4) `include "includes/ahxi_fsm_code.vh" ) fsm_pgm_mem_i ( .rclk (mclk), // input .raddr (pgm_addr), // input[10:0] Loading @@ -365,10 +351,112 @@ sequence = [{LBL:'POR', ADR: 0x0, ACT: NOP}, .wclk (aclk), // input .waddr (pgm_waddr), // input[10:0] .we (pgm_wd), // input .web (8'hff), // input[7:0] .web (4'hff), // input[7:0] .data_in (pgm_ad) // input[17:0] ); action_decoder action_decoder_i ( .clk (mclk), // input .enable (), // input .data (), // input[10:0] .PXSERR_DIAG_X (), // output reg .SIRQ_DHR (), // output reg .SIRQ_DP (), // output reg .SIRQ_DS (), // output reg .SIRQ_IF (), // output reg .SIRQ_PS (), // output reg .SIRQ_SDB (), // output reg .SIRQ_TFE (), // output reg .SIRQ_UF (), // output reg .PFSM_STARTED (), // output reg .PCMD_CR_CLEAR (), // output reg .PCMD_CR_SET (), // output reg .PXCI0_CLEAR (), // output reg .PXSSTS_DET_1 (), // output reg .SSTS_DET_OFFLINE (), // output reg .SET_UPDATE_SIG (), // output reg .UPDATE_SIG (), // output reg .UPDATE_ERR_STS (), // output reg .UPDATE_PIO (), // output reg .UPDATE_PRDBC (), // output reg .CLEAR_BSY_DRQ (), // output reg .CLEAR_BSY_SET_DRQ (), // output reg .SET_BSY (), // output reg .SET_STS_7F (), // output reg .SET_STS_80 (), // output reg .XFER_CNTR_CLEAR (), // output reg .DECR_DWC (), // output reg .FIS_FIRST_FLUSH (), // output reg .CLEAR_CMD_TO_ISSUE (), // output reg .DMA_ABORT (), // output reg .DMA_PRD_IRQ_CLEAR (), // output reg .XMIT_COMRESET (), // output reg .SEND_SYNC_ESC (), // output reg .SET_OFFLINE (), // output reg .R_OK (), // output reg .R_ERR (), // output reg .FETCH_CMD (), // output reg .ATAPI_XMIT (), // output reg .CFIS_XMIT (), // output reg .DX_XMIT (), // output reg .GET_DATA_FIS (), // output reg .GET_DSFIS (), // output reg .GET_IGNORE (), // output reg .GET_PSFIS (), // output reg .GET_RFIS (), // output reg .GET_SDBFIS (), // output reg .GET_UFIS () // output reg ); condition_mux condition_mux_i ( .clk (mclk), // input .sel (), // input[7:0] .condition (), // output .ST_NB_ND (), // input .PXCI0_NOT_CMDTOISSUE (), // input .PCTI_CTBAR_XCZ (), // input .PCTI_XCZ (), // input .NST_D2HR (), // input .NPD_NCA (), // input .CHW_DMAA (), // input .SCTL_DET_CHANGED_TO_4 (), // input .SCTL_DET_CHANGED_TO_1 (), // input .PXSSTS_DET_NE_3 (), // input .PXSSTS_DET_EQ_1 (), // input .NPCMD_FRE (), // input .FIS_OK (), // input .FIS_ERR (), // input .FIS_FERR (), // input .FIS_EXTRA (), // input .FIS_FIRST_INVALID (), // input .FR_D2HR (), // input .FIS_DATA (), // input .FIS_ANY (), // input .NB_ND_D2HR_PIO (), // input .D2HR (), // input .SDB (), // input .DMA_ACT (), // input .DMA_SETUP (), // input .BIST_ACT_FE (), // input .BIST_ACT (), // input .PIO_SETUP (), // input .NB_ND (), // input .TFD_STS_ERR (), // input .FIS_I (), // input .PIO_I (), // input .NPD (), // input .PIOX (), // input .XFER0 (), // input .PIOX_XFER0 (), // input .CTBAA_CTBAP (), // input .CTBAP (), // input .CTBA_B (), // input .CTBA_C (), // input .TX_ERR (), // input .SYNCESC_ERR (), // input .DMA_PRD_IRQ_PEND (), // input .X_RDY_COLLISION () // input ); /* Loading
generated/action_decoder.v +48 −48 Original line number Diff line number Diff line /******************************************************************************* * Module: action_decoder * Date:2016-01-18 * Date:2016-01-19 * Author: auto-generated file, see ahci_fsm_sequence.py * Description: Decode sequencer code to 1-hot actions *******************************************************************************/ Loading Loading @@ -60,52 +60,52 @@ module action_decoder ( output reg GET_UFIS); always @(posedge clk) begin PXSERR_DIAG_X <= enable && data[ 2] && data[ 0]; SIRQ_DHR <= enable && data[ 3] && data[ 0]; SIRQ_DP <= enable && data[ 4] && data[ 0]; SIRQ_DS <= enable && data[ 5] && data[ 0]; SIRQ_IF <= enable && data[ 6] && data[ 0]; SIRQ_PS <= enable && data[ 7] && data[ 0]; SIRQ_SDB <= enable && data[ 8] && data[ 0]; SIRQ_TFE <= enable && data[ 9] && data[ 0]; SIRQ_UF <= enable && data[10] && data[ 0]; PFSM_STARTED <= enable && data[ 2] && data[ 1]; PCMD_CR_CLEAR <= enable && data[ 3] && data[ 1]; PCMD_CR_SET <= enable && data[ 4] && data[ 1]; PXCI0_CLEAR <= enable && data[ 5] && data[ 1]; PXSSTS_DET_1 <= enable && data[ 6] && data[ 1]; SSTS_DET_OFFLINE <= enable && data[ 7] && data[ 1]; SET_UPDATE_SIG <= enable && data[ 8] && data[ 1]; UPDATE_SIG <= enable && data[ 9] && data[ 1]; UPDATE_ERR_STS <= enable && data[10] && data[ 1]; UPDATE_PIO <= enable && data[ 3] && data[ 2]; UPDATE_PRDBC <= enable && data[ 4] && data[ 2]; CLEAR_BSY_DRQ <= enable && data[ 5] && data[ 2]; CLEAR_BSY_SET_DRQ <= enable && data[ 6] && data[ 2]; SET_BSY <= enable && data[ 7] && data[ 2]; SET_STS_7F <= enable && data[ 8] && data[ 2]; SET_STS_80 <= enable && data[ 9] && data[ 2]; XFER_CNTR_CLEAR <= enable && data[10] && data[ 2]; DECR_DWC <= enable && data[ 4] && data[ 3]; FIS_FIRST_FLUSH <= enable && data[ 5] && data[ 3]; CLEAR_CMD_TO_ISSUE <= enable && data[ 6] && data[ 3]; DMA_ABORT <= enable && data[ 7] && data[ 3]; DMA_PRD_IRQ_CLEAR <= enable && data[ 8] && data[ 3]; XMIT_COMRESET <= enable && data[ 9] && data[ 3]; SEND_SYNC_ESC <= enable && data[10] && data[ 3]; SET_OFFLINE <= enable && data[ 5] && data[ 4]; R_OK <= enable && data[ 6] && data[ 4]; R_ERR <= enable && data[ 7] && data[ 4]; FETCH_CMD <= enable && data[ 8] && data[ 4]; ATAPI_XMIT <= enable && data[ 9] && data[ 4]; CFIS_XMIT <= enable && data[10] && data[ 4]; DX_XMIT <= enable && data[ 6] && data[ 5]; GET_DATA_FIS <= enable && data[ 7] && data[ 5]; GET_DSFIS <= enable && data[ 8] && data[ 5]; GET_IGNORE <= enable && data[ 9] && data[ 5]; GET_PSFIS <= enable && data[10] && data[ 5]; GET_RFIS <= enable && data[ 7] && data[ 6]; GET_SDBFIS <= enable && data[ 8] && data[ 6]; GET_UFIS <= enable && data[ 9] && data[ 6]; PXSERR_DIAG_X <= enable && data[ 1] && data[ 0]; SIRQ_DHR <= enable && data[ 2] && data[ 0]; SIRQ_DP <= enable && data[ 3] && data[ 0]; SIRQ_DS <= enable && data[ 4] && data[ 0]; SIRQ_IF <= enable && data[ 5] && data[ 0]; SIRQ_PS <= enable && data[ 6] && data[ 0]; SIRQ_SDB <= enable && data[ 7] && data[ 0]; SIRQ_TFE <= enable && data[ 8] && data[ 0]; SIRQ_UF <= enable && data[ 9] && data[ 0]; PFSM_STARTED <= enable && data[10] && data[ 0]; PCMD_CR_CLEAR <= enable && data[ 2] && data[ 1]; PCMD_CR_SET <= enable && data[ 3] && data[ 1]; PXCI0_CLEAR <= enable && data[ 4] && data[ 1]; PXSSTS_DET_1 <= enable && data[ 5] && data[ 1]; SSTS_DET_OFFLINE <= enable && data[ 6] && data[ 1]; SET_UPDATE_SIG <= enable && data[ 7] && data[ 1]; UPDATE_SIG <= enable && data[ 8] && data[ 1]; UPDATE_ERR_STS <= enable && data[ 9] && data[ 1]; UPDATE_PIO <= enable && data[10] && data[ 1]; UPDATE_PRDBC <= enable && data[ 3] && data[ 2]; CLEAR_BSY_DRQ <= enable && data[ 4] && data[ 2]; CLEAR_BSY_SET_DRQ <= enable && data[ 5] && data[ 2]; SET_BSY <= enable && data[ 6] && data[ 2]; SET_STS_7F <= enable && data[ 7] && data[ 2]; SET_STS_80 <= enable && data[ 8] && data[ 2]; XFER_CNTR_CLEAR <= enable && data[ 9] && data[ 2]; DECR_DWC <= enable && data[10] && data[ 2]; FIS_FIRST_FLUSH <= enable && data[ 4] && data[ 3]; CLEAR_CMD_TO_ISSUE <= enable && data[ 5] && data[ 3]; DMA_ABORT <= enable && data[ 6] && data[ 3]; DMA_PRD_IRQ_CLEAR <= enable && data[ 7] && data[ 3]; XMIT_COMRESET <= enable && data[ 8] && data[ 3]; SEND_SYNC_ESC <= enable && data[ 9] && data[ 3]; SET_OFFLINE <= enable && data[10] && data[ 3]; R_OK <= enable && data[ 5] && data[ 4]; R_ERR <= enable && data[ 6] && data[ 4]; FETCH_CMD <= enable && data[ 7] && data[ 4]; ATAPI_XMIT <= enable && data[ 8] && data[ 4]; CFIS_XMIT <= enable && data[ 9] && data[ 4]; DX_XMIT <= enable && data[10] && data[ 4]; GET_DATA_FIS <= enable && data[ 6] && data[ 5]; GET_DSFIS <= enable && data[ 7] && data[ 5]; GET_IGNORE <= enable && data[ 8] && data[ 5]; GET_PSFIS <= enable && data[ 9] && data[ 5]; GET_RFIS <= enable && data[10] && data[ 5]; GET_SDBFIS <= enable && data[ 7] && data[ 6]; GET_UFIS <= enable && data[ 8] && data[ 6]; end endmodule
generated/condition_mux.v +4 −3 Original line number Diff line number Diff line /******************************************************************************* * Module: condition_mux * Date:2016-01-18 * Date:2016-01-19 * Author: auto-generated file, see ahci_fsm_sequence.py * Description: Select condition *******************************************************************************/ Loading Loading @@ -56,7 +56,7 @@ module condition_mux ( input DMA_PRD_IRQ_PEND, input X_RDY_COLLISION); wire [43:0] masked; wire [44:0] masked; reg [ 5:0] cond_r; assign condition = |cond_r; Loading Loading @@ -105,6 +105,7 @@ module condition_mux ( assign masked[41] = SYNCESC_ERR && sel[ 6] && sel[ 4] && sel[ 2]; assign masked[42] = DMA_PRD_IRQ_PEND && sel[ 7] && sel[ 4] && sel[ 2]; assign masked[43] = X_RDY_COLLISION && sel[ 6] && sel[ 5] && sel[ 2]; assign masked[44] = !(|sel); // always TRUE condition (sel ==0) always @(posedge clk) begin cond_r[ 0] <= |masked[ 7: 0]; Loading @@ -112,6 +113,6 @@ module condition_mux ( cond_r[ 2] <= |masked[23:16]; cond_r[ 3] <= |masked[31:24]; cond_r[ 4] <= |masked[39:32]; cond_r[ 5] <= |masked[43:40]; cond_r[ 5] <= |masked[44:40]; end endmodule
helpers/ahci_fsm_sequence.py +166 −6 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ action_decoder_module_name= 'action_decoder' condition_mux_verilog_path= '../generated/condition_mux.v' condition_mux_module_name= 'condition_mux' condition_mux_fanout = 8 code_rom_path= '../includes/ahxi_fsm_code.vh' #Set actions, conditions to empty string to rebuild list. Then edit order and put here actions = ['NOP', # CTRL_STAT Loading Loading @@ -477,13 +478,15 @@ module %s ( num_inputs += 1 v >>= 1 maximal_length = max([len(n) for n in conditions]) numregs = (len(conditions) + fanout - 1) // fanout # numregs = (len(conditions) + fanout - 1) // fanout numregs = (len(conditions) + fanout) // fanout # one more bit for 'always' (sel == 0) header = header_template%(module_name, datetime.date.today().isoformat(), os.path.basename(__file__), module_name, num_inputs-1) print(header,file=file) for input_name in conditions[:len(conditions)-1]: print(" input %s,"%(input_name),file=file) print(" input %s);\n"%(conditions[-1]),file=file) print(" wire [%2d:0] masked;"%(len(conditions)-1),file=file) # print(" wire [%2d:0] masked;"%(len(conditions)-1),file=file) print(" wire [%2d:0] masked;"%(len(conditions)),file=file) if numregs > 1: print(" reg [%2d:0] cond_r;\n"%(numregs-1),file=file) else: Loading @@ -502,10 +505,13 @@ module %s ( if d & (1 << nb): print (" && sel[%2d]"%(nb), end="", file=file) print (";", file=file) print(" assign masked[%2d] = !(|sel); // always TRUE condition (sel ==0)"%(len(conditions)), file=file) print ("\n always @(posedge clk) begin", file=file) for nb in range (numregs): ll = nb * fanout hl = min(ll + fanout, len(conditions)) -1 # hl = min(ll + fanout, len(conditions)) -1 hl = min(ll + fanout -1, len(conditions)) if numregs > 1: print (" cond_r[%2d] <= "%(nb), end="", file=file) else: Loading Loading @@ -562,6 +568,111 @@ module %s ( print (";", file=file) print (" end", file=file) print("endmodule",file=file) #def code_generator (sequence, actions, action_vals,conditions, condition_vals, labels): def code_generator (sequence, action_vals, condition_vals, labels): wait_act = 0x10000 last_act = 0x20000 act_mask = 0x0ffff # actually 0x007ff (11 bits) is enough goto_mask = 0x003ff # 10-bit address cond_mask = 0xff # before << cond_shift = 10 # jump_mode = False; code=[] for a, l in enumerate (sequence): # checks if not jump_mode: if (IF in l) or (GOTO in l): raise Exception ("Unexpected line %d: %s - was expecting action, not GOTO"%(a,str(l))) else: if (LBL in l) or (ACT in l) or (ADDR in l): jump_mode = False # set ACT mode before processing, set GOTO mode - after processing if IF in sequence[a-1]: # first ACT after JUMP raise Exception ("Last jump (%d: %s) should be unconditional GOTO"%(a-1,str(sequence[a-1]))) d=0 if not jump_mode: if ACT in l: act = action_vals[l[ACT]] if act != (act & act_mask): raise Exception ("ACT = 0x%x does not fit into designated field (0x%x) in line %d:%s"%(act, act_mask, a,str(l))) d=act | (0,wait_act)[l[ACT].endswith('*')] if (GOTO in sequence[a+1]): jump_mode = True d |= last_act else: # jump mode goto = labels[l[GOTO]] if goto != (goto & goto_mask): raise Exception ("GOTO = 0x%x does not fit into designated field (0x%x) in line %d:%s"%(goto, goto_mask, a,str(l))) cond = 0 if IF in l: cond = condition_vals[l[IF]] if cond != (cond & cond_mask): raise Exception ("IF = 0x%x does not fit into designated field (0x%x) in line %d:%s"%(cond, cond_mask, a,str(l))) d = goto | (cond << cond_shift) code.append(d) return code def create_with_parity (init_data, # numeric data (may be less than full array num_bits, # number of bits in item, valid: 1,2,4,8,9,16,18,32,36,64,72 # start_bit, # bit number to start filling from full_bram): # true if ramb36, false - ramb18 d = num_bits num_bits8 = 1; while d > 1: d >>= 1 num_bits8 <<= 1 bsize = (0x4000,0x8000)[full_bram] bdata = [0 for i in range(bsize)] sb = 0 for item in init_data: for bt in range (num_bits8): bdata[sb+bt] = (item >> bt) & 1; sb += num_bits8 data = [] for i in range (len(bdata)//256): d = 0; for b in range(255, -1,-1): d = (d<<1) + bdata[256*i+b] data.append(d) data_p = [] num_bits_p = num_bits8 >> 3 sb = 0 print ("num_bits=",num_bits) print ("num_bits8=",num_bits8) print ("num_bits_p=",num_bits_p) if num_bits_p: pbsize = bsize >> 3 pbdata = [0 for i in range(pbsize)] for item in init_data: # print ("item = 0x%x, p = 0x%x"%(item,item >> num_bits8)) for bt in range (num_bits_p): pbdata[sb+bt] = (item >> (bt+num_bits8)) & 1; # print ("pbdata[%d] = 0x%x"%(sb+bt, pbdata[sb+bt])) sb += num_bits_p for i in range (len(pbdata)//256): d = 0; for b in range(255, -1,-1): d = (d<<1) + pbdata[256*i+b] data_p.append(d) # print(bdata) # print(data) # print(pbdata) # print(data_p) return {'data':data,'data_p':data_p} def print_params(data,out_file_name): with open(out_file_name,"w") as out_file: for i, v in enumerate(data['data']): if v: print (", .INIT_%02X (256'h%064X)"%(i,v), file=out_file) # if (include_parity): for i, v in enumerate(data['data_p']): if v: print (", .INITP_%02X (256'h%064X)"%(i,v), file=out_file) #print (sequence) ln = 0 while ln < len(sequence): Loading Loading @@ -644,8 +755,13 @@ if sort_conditions: #Assign values to actions action_vals={} vals = bin_cnk (*actions_cnk) indx = 0 for i, v in enumerate (actions): action_vals[v]= vals[i] if v == 'NOP': action_vals[v]= 0 else: action_vals[v]= vals[indx] indx += 1 #Assign values to conditions condition_vals={} vals = bin_cnk (*conditions_cnk) Loading Loading @@ -674,8 +790,8 @@ for i,c in enumerate(conditions): # print ("%02d: %s"%(i,c)) print ("%s"%(c)) print ("action_vals=", action_vals) print ("condition_vals=",condition_vals) #print ("action_vals=", action_vals) #print ("condition_vals=",condition_vals) #for i, line in enumerate(sequence): # print ("%03x: %s"%(i,line)) Loading @@ -694,5 +810,49 @@ else: condition_mux_verilog(conditions, condition_vals,condition_mux_module_name, condition_mux_fanout, out_file) print ("AHCI FSM conditions multiplexer is written to %s"%(os.path.abspath(os.path.join(os.path.dirname(__file__), condition_mux_verilog_path)))) code = code_generator (sequence, action_vals, condition_vals, labels) #print_params(create_with_parity(code, 18, 0, False),os.path.abspath(os.path.join(os.path.dirname(__file__), code_rom_path))) print_params(create_with_parity(code, 18, False),os.path.abspath(os.path.join(os.path.dirname(__file__), code_rom_path))) print ("AHCI FSM code data is written to %s"%(os.path.abspath(os.path.join(os.path.dirname(__file__), code_rom_path)))) #longest_label = max([len(labels[l]) for l in labels.keys()]) longest_label = max([len(l) for l in labels]) longest_act = max([len(act) for act in actions]) longest_cond = max([len(cond) for cond in conditions]) format_act = "%%%ds do %%s%%s"%(longest_label+1) format_cond = "%%%ds %%%ds goto %%s"%(longest_label+1, longest_cond+3) #print ("format_act=", format_act) #print ("format_cond=",format_cond) print ("\n code:") for a,c in enumerate(code): l = sequence[a] if LBL in l: print() print ("%03x: %05x #"%(a,c),end = "") if (ACT in l) or (LBL in l): try: lbl = l[LBL]+":" except: lbl = "" try: act = l[ACT] except: act = "NOP" wait = "" if act.endswith('*'): wait = ", WAIT DONE" act = act[0:-1] print(format_act%(lbl,act,wait)) else: try: cond = "if "+l[IF] except: cond = "always" cond += ' '*(longest_cond+3-len(cond)) print(format_cond%("",cond,l[GOTO])) # print ("%03x: %05x # %s"%(a,c,str(sequence[a]))) #condition_mux_verilog(conditions, condition_vals, 'condition_mux',100, file=None) No newline at end of file