📄 fpa3x_dev.c
字号:
/* * Function to test the TI data path using the TI addition and multiplication * single and double precision command register instructions. * For addition: reg1 = reg2 + reg3, * where reg2 = 0 and reg3 = different values. * For multiplication: reg1 = reg2 * reg3, * where reg2 = 1 and reg3 = different values. */tipath_test(){ register u_int s, e, f, r1, r2, r3, data; u_int ms_exp, ls_exp, ms_obs, ls_obs; /* single precision operations */ send_message(0,VERBOSE,tst_tipath,"single"); r1 = 0; r2 = 1; r3 = 2; for (s = 0; s <= 1; s++) { for (e = 1; e < S_EMAX; e<<=1) { for (f = 0; f < S_FBITS; f++) { ms_exp = (s<<S_SIGNBIT) | (e<<S_FBITS) | (1<<f); ls_exp = SZERO; if (write_datareg(r3,ms_exp,ls_exp)) return; data = C_REG3(r3) | C_REG2(r2) | C_REG1(r1); if (write_datareg(r2,SZERO,ls_exp)) return; if (write_fpa((u_int *)CWSP_ADD,data,ON)) return; if (read_datareg(r1,&ms_obs,&ls_obs)) return; if (ms_obs != ms_exp || ls_obs != ls_exp) send_message(FPERR,ERROR,er_tipath,ms_exp,ls_exp,ms_obs,ls_obs); if (write_datareg(r2,SONE,X)) return; if (write_fpa((u_int *)CWSP_MULT,data,ON)) return; if (read_datareg(r1,&ms_obs,&ls_obs)) return; if (ms_obs != ms_exp || ls_obs != ls_exp) send_message(FPERR,ERROR,er_tipath,ms_exp,ls_exp,ms_obs,ls_obs); if (++r1 >= FPA_NDATA_REGS) r1 = 0; if (++r2 >= FPA_NDATA_REGS) r2 = 0; if (++r3 >= FPA_NDATA_REGS) r3 = 0; } } } /* double precision operations */ send_message(0,VERBOSE,tst_tipath,"double"); r1 = 0; r2 = 1; r3 = 2; for (s = 0; s <= 1; s++) { for (e = 1; e < D_EMAX; e<<=1) { for (f = 0; f < D_FBITS; f++) { ls_exp = 1 << f; ms_exp = (s<<(D_SIGNBIT-32)) | (e<<(D_FBITS-32)); if (f >= 32) ms_exp += (1<<(f-32)); if (write_datareg(r3,ms_exp,ls_exp)) return; data = C_REG3(r3) | C_REG2(r2) | C_REG1(r1); if (write_datareg(r2,DZERO_M,DZERO_L)) return; if (write_fpa((u_int *)CWDP_ADD,data,ON)) return; if (read_datareg(r1,&ms_obs,&ls_obs)) return; if (ms_obs != ms_exp || ls_obs != ls_exp) send_message(FPERR,ERROR,er_tipath,ms_exp,ls_exp,ms_obs,ls_obs); if (write_datareg(r2,DONE_M,DONE_L)) return; if (write_fpa((u_int *)CWDP_MULT,data,ON)) return; if (read_datareg(r1,&ms_obs,&ls_obs)) return; if (ms_obs != ms_exp || ls_obs != ls_exp) send_message(FPERR,ERROR,er_tipath,ms_exp,ls_exp,ms_obs,ls_obs); if (++r1 >= FPA_NDATA_REGS) r1 = 0; if (++r2 >= FPA_NDATA_REGS) r2 = 0; if (++r3 >= FPA_NDATA_REGS) r3 = 0; } } }}/* * Function to test most of FPA-3X instructions operations. */tiop_test(){ send_message(0,VERBOSE,tst_tiop,"single precision short"); tiop_spshort(); send_message(0,VERBOSE,tst_tiop,"double precision short"); tiop_dpshort(); send_message(0,VERBOSE,tst_tiop,"single precision extended"); tiop_spextend(); send_message(0,VERBOSE,tst_tiop,"single precision 2-operand extended"); tiop_spextend2(); send_message(0,VERBOSE,tst_tiop,"double precision extended"); tiop_dpextend(); send_message(0,VERBOSE,tst_tiop,"single precision command register"); tiop_spcmdreg(); send_message(0,VERBOSE,tst_tiop,"double precision command register"); tiop_dpcmdreg();}/* * Function to test single precision short operation. */tiop_spshort(){ register u_int inst, r1, k, exp; u_int ms, ls; for (k = 0; spshort[k].inst; k++) { for (r1 = 0; r1 < FPA_NSHORT_REGS; r1++) { if (write_datareg(r1,spshort[k].reg1,SZERO)) return; inst = spshort[k].inst | SP_REG1(r1); if (write_fpa((u_int *)inst,spshort[k].op,ON)) return; if (read_datareg(r1,&ms,&ls)) return; exp = spshort[k].result; if (ms != exp || ls != SZERO) send_message(FPERR,ERROR,er_tiop,inst,exp,SZERO,ms,ls); } }}/* * Function to test double precision short operation. */tiop_dpshort(){ register u_int inst, r1, k, exp; u_int ms, ls; for (k = 0; dpshort[k].inst; k++) { for (r1 = 0; r1 < FPA_NSHORT_REGS; r1++) { if (write_datareg(r1,dpshort[k].reg1,DZERO_L)) return; inst = dpshort[k].inst | DP_REG1(r1); if (write_fpa((u_int *)inst,dpshort[k].op,ON)) return; if (write_fpa((u_int *)DP_LSW,DZERO_L,ON)) return; if (read_datareg(r1,&ms,&ls)) return; exp = dpshort[k].result; if (ms != exp || ls != DZERO_L) send_message(FPERR,ERROR,er_tiop,inst,exp,DZERO_L,ms,ls); } }}/* * Function to test single precision extended operation. */tiop_spextend(){ register u_int inst, r1, r2, exp, k; u_int ms, ls; for (k = 0; spext[k].inst; k++) { for (r1=0, r2=1; r2<FPA_NSHORT_REGS; r1++, r2++) { if (write_datareg(r1,SZERO,SZERO)) return; if (write_datareg(r2,spext[k].reg2,SZERO)) return; inst = spext[k].inst | X_REG2(r2); if (write_fpa((u_int *)inst,spext[k].op,ON)) return; inst = X_LSW | X_REG1(r1); if (write_fpa((u_int *)inst,X,ON)) return; if (read_datareg(r1,&ms,&ls)) return; exp = spext[k].reg1; if (ms != exp || ls != SZERO) send_message(FPERR,ERROR,er_tiop,inst,exp,SZERO,ms,ls); } }}/* * Function to test single precision extended operation with 2 operands. */tiop_spextend2(){ register u_int inst, r1, r2, exp, k; u_int ms, ls; for (k = 0; spext2[k].inst; k++) { for (r1=0, r2=0; r2<FPA_NSHORT_REGS; r1++, r2++) { if (write_datareg(r1,SZERO,SZERO)) return; if (write_datareg(r2,spext2[k].reg2,SZERO)) return; inst = spext2[k].inst | X_REG2(r2); if (write_fpa((u_int *)inst,spext2[k].op1,ON)) return; inst = X_LSW | X_REG1(r1); if (write_fpa((u_int *)inst,spext2[k].op2,ON)) return; if (read_datareg(r1,&ms,&ls)) return; exp = spext2[k].reg1; if (ms != exp || ls != SZERO) send_message(FPERR,ERROR,er_tiop,inst,exp,SZERO,ms,ls); } }}/* * Function to test double precision extended operation. */tiop_dpextend(){ register u_int inst, r1, r2, exp, k; u_int ms, ls; for (k = 0; dpext[k].inst; k++) { for (r1=0, r2=1; r2<FPA_NSHORT_REGS; r1++, r2++) { if (write_datareg(r1,DZERO_M,DZERO_L)) return; if (write_datareg(r2,dpext[k].reg2,DZERO_L)) return; inst = dpext[k].inst | X_REG2(r2); if (write_fpa((u_int *)inst,dpext[k].op,ON)) return; inst = X_LSW | X_REG1(r1); if (write_fpa((u_int *)inst,X,ON)) return; if (read_datareg(r1,&ms,&ls)) return; exp = dpext[k].reg1; if (ms != exp || ls != DZERO_L) send_message(FPERR,ERROR,er_tiop,inst,exp,DZERO_L,ms,ls); } }}/* * Function to test single precision command register operation. */tiop_spcmdreg(){ register u_int inst, r1, r2, r3, r4, data, exp, k; u_int ms, ls; for (k = 0; inst = spcmd[k].inst; k++) { for (r1=0, r2=1, r3=2, r4=3; r4<FPA_NDATA_REGS; r1++, r2++, r3++, r4++) { if (write_datareg(r1,SZERO,SZERO)) return; if (write_datareg(r2,spcmd[k].reg2,SZERO)) return; if (write_datareg(r3,spcmd[k].reg3,SZERO)) return; if (write_datareg(r4,spcmd[k].reg4,SZERO)) return; data = C_REG1(r1) | C_REG2(r2) | C_REG3(r3) | C_REG4(r4); if (write_fpa((u_int *)inst,data,ON)) return; if (read_datareg(r1,&ms,&ls)) return; exp = spcmd[k].reg1; if (ms != exp || ls != SZERO) send_message(FPERR,ERROR,er_tiop,inst,exp,SZERO,ms,ls); } }}/* * Function to test double precision command register operation. */tiop_dpcmdreg(){ register u_int inst, r1, r2, r3, r4, data, exp, k; u_int ms, ls; for (k = 0; inst = dpcmd[k].inst; k++) { for (r1=0, r2=1, r3=2, r4=3; r4<FPA_NDATA_REGS; r1++, r2++, r3++, r4++) { if (write_datareg(r1,DZERO_M,DZERO_L)) return; if (write_datareg(r2,dpcmd[k].reg2,DZERO_L)) return; if (write_datareg(r3,dpcmd[k].reg3,DZERO_L)) return; if (write_datareg(r4,dpcmd[k].reg4,DZERO_L)) return; data = C_REG1(r1) | C_REG2(r2) | C_REG3(r3) | C_REG4(r4); if (write_fpa((u_int *)inst,data,ON)) return; if (read_datareg(r1,&ms,&ls)) return; exp = dpcmd[k].reg1; if (ms != exp || ls != DZERO_L) send_message(FPERR,ERROR,er_tiop,inst,exp,DZERO_L,ms,ls); } }}/* * Function to test TI status by generating all possible status reported * to the WSTATUS register. */tistatus_test(){ send_message(0,VERBOSE,tst_tistat,"alu"); ti_status(alu); send_message(0,VERBOSE,tst_tistat,"multiplier"); ti_status(mul);}/* * Function uses the specified test table to issue instruction then * verifies the TI status reported in WSTATUS register bits 8 thru 11. * Note that all Weitek operation takes the form: reg1 = reg2 op reg 3. */ti_status(tbl)struct tistat_tbl *tbl;{ register u_int inst, data, k; u_int wstat, wstat_exp; for (k = 0; inst = tbl[k].inst; k++) { if (write_datareg(2,tbl[k].reg2_ms,tbl[k].reg2_ls)) return; if (write_datareg(3,tbl[k].reg3_ms,tbl[k].reg3_ls)) return; data = C_REG2(2) | C_REG3(3); if (write_fpa((u_int *)inst,data,ON)) return; if (read_fpa(&fpa->fp_wstatus_stable,&wstat,ON)) return; wstat &= TISTAT_MASK; wstat_exp = tbl[k].stat; if (fpa_version == FPA3X_VERSION) { if (wstat_exp == TI_FINEX) wstat_exp = TI_INFIN; } if (wstat != wstat_exp) send_message(FPERR,ERROR,er_tistat,wstat_exp,wstat); if (write_fpa(&fpa->fp_clear_pipe,X,ON)) return; }}/* * Function to test the TI timing when many similar instructions are * quickly issued in succession. */timing_test(){ register int k; send_message(0,VERBOSE,tst_timing); for (k = 0; k < 100; k++) { timing_spshort(); timing_dpshort(); timing_extend(); timing_cmdreg(); }}/* * Function to test TI timing using single precision short instructions. */timing_spshort(){ register u_int k, inst, r1; u_int ms, ls; r1 = 0; for (k = 0; inst = timsp[k].inst; k++) { if (write_datareg(r1,timsp[k].reg1,SZERO)) return; inst |= SP_REG1(r1); if (write_fpa((u_int *)inst,timsp[k].op,ON)) return; if (read_datareg(r1,&ms,&ls)) return; if (ms != timsp[k].result || ls != SZERO) send_message(FPERR,ERROR,er_timing,timsp[k].result,SZERO,ms,ls); if (++r1 >= FPA_NDATA_REGS) r1 = 0; }}/* * Function to test TI timing using double precision short instructions. */timing_dpshort(){ register u_int k, inst, r1; u_int ms, ls; r1 = 0; for (k = 0; inst = timdp[k].inst; k++) { if (write_datareg(r1,timdp[k].reg1,DZERO_L)) return; inst |= SP_REG1(r1); if (write_fpa((u_int *)inst,timdp[k].op,ON)) return; if (write_fpa((u_int *)DP_LSW,DZERO_L,ON)) return; if (read_datareg(r1,&ms,&ls)) return; if (ms != timdp[k].result || ls != DZERO_L) send_message(FPERR,ERROR,er_timing,timdp[k].result,DZERO_L,ms,ls); if (++r1 >= FPA_NDATA_REGS) r1 = 0; }}/* * Function to test TI timing using extended instructions. */timing_extend(){ register u_int k, inst, r1, r2, r3; u_int ms, ls; r1 = 0; r2 = 1; r3 = 2; for (k = 0; inst = timext[k].inst; k++) { if (write_datareg(r2,timext[k].reg2,DZERO_L)) return; if (write_datareg(r3,timext[k].reg3,DZERO_L)) return; inst |= X_REG2(r2); if (write_fpa((u_int *)inst,timext[k].op,ON)) return; inst = X_LSW | X_REG1(r1) | X_REG3(r3); if (write_fpa((u_int *)inst,DZERO_L,ON)) return; if (read_datareg(r1,&ms,&ls)) return; if (ms != timext[k].reg1 || ls != DZERO_L) send_message(FPERR,ERROR,er_timing,timext[k].reg1,DZERO_L,ms,ls); if (++r1 >= FPA_NDATA_REGS) r1 = 0; if (++r2 >= FPA_NDATA_REGS) r2 = 0; if (++r3 >= FPA_NDATA_REGS) r3 = 0; }}/* * Function to test TI timing using command register instructions. */timing_cmdreg(){ register u_int k, inst, r1, r2, data; u_int ms, ls; r1 = 0; r2 = 1; for (k = 0; inst = timcmd[k].inst; k++) { if (write_datareg(r2,timcmd[k].ms2,timcmd[k].ls2)) return; data = C_REG2(r2) | C_REG1(r1); if (write_fpa((u_int *)inst,data,ON)) return; if (read_datareg(r1,&ms,&ls)) return; if (ms != timcmd[k].ms1 || ls != timcmd[k].ls1) send_message(FPERR,ERROR,er_timing,timcmd[k].ms1,timcmd[k].ls1,ms,ls); if (++r1 >= FPA_NDATA_REGS) r1 = 0; if (++r2 >= FPA_NDATA_REGS) r2 = 0; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -