MODULE mem68k //XILINX Webpack ISE 4.2WP3.0 (installs on Windows 10 too) latest Xilinx ISE software doesn't have ABEL language support //Converted from LordV A600 4 chip 8 meg memory cpld verilog code to abel code for single 4M x 16 chip //4K_refresh edo (or fpm?) 4m x 16 dram, column select to aa0..aa9, row select to aa0..aa11 //v4x,6x use 5V edo KM416C4104 (or fpm KM414C4100), cas before ras refresh 4k refresh product, suffix AS, BS, CS, etc. //V history //28.10.2018 use programmable grounds v4x, timing with -15ns part? (66,69nS certain thing) //11.10.2018 autoconfig skip style: force ram autoconfig after one external autoconfig cycle even if config in signal inactive. (v61,62 need feed +voltage to pin) //4.10.2018 8/4+2+1 or 4+2+1 config offers (1meg blocks), rfsh_ras possible other race glitch looked at //23.9 8/4+2 or 4+2 meg config define, address range regardless of autoconfig define //14.9.2018 try fix refresh signal (remove rfsh_cas.aclr=!cpu_nas.pin;) in previous versions of this code to fix restarting mc68hc000 issue //9.9/8.9/5.9.2018, 8 - 4/4+2 - 2 meg //8.8.2018 board shutup. 4Meg autoconfigs to 20/40/600000 //31.7.2018 make skip one autoconfig, for cdtv, config out on v5x //didn't happen: 19.7.2018 special version 6Meg 400000..9fffff no-autoconfig + "ranger ram" 1.5 Meg at c00000..d7ffff //8.7.2018,12.5.2018 v6x - 5volt dram, difference: pin 11 v5x bufena to config in v6x //1.5.2018 unfinished 29.12.2017 version development continue //29.12.2017 make .jed file R583, ram on regardless of autoconfig, v58/59 config in //26.12.2017 specify grounded of floating io-pins as outputs with value=0(gnd); //26.12.2017 option, ram on regardless of autoconfig, v58/59 config in only (no config out) (use pull-up resistor to keep autoconfig away?) //4.12.2017 option, config in instead of out for v58/59 //4.12.2017 option, 4MByte instead of 8MByte //13.8.2017 pin numbers for vqfp64 version v58 (v59) //14.8.2017 pin numbers for plcc xcr3128xl version (one pin corrected 4.12.2017) //30/28/26.7.2017 eeeedits //19.2.2015: when (dly_nas.pin=='1'), eikä '0' //21.6.2014>01.03.2014>09.02.2014>10.7.2013>21.june.2013 DECLARATIONS //define one pcb version, comment out others //v40 =1; //v42 =1; //same for v43 v5x =1; v5xconfigin =1; //V58,V59 choose pin 22 function //v5x =1; v5xconfigout =1; //v6x =1; //vplcc128x =1; //define if autoconfig logic included use_autoconfig_logic = 1; //skipoffer8megs =1; //skip 8 meg config try, start with 4 then 2 meg then 1 meg //force_config_after_one_other = 1; //for e.g. cdtv, start mem autoconfig even if config_in signal inactive (make config_in inactive for v59 config_out version) //todo: remaining memory appear at $c0 0000 and somewhere? //Address Range Regardless of Autoconfig, RAM responds in these addresses even without having been autoconfigured //use_ARRA =1; //define this to use that //this seemeed to have a bad expression in 23.9.2018 version //Also, 4 high address bits (a4h) instead of 3 (a3h) ARRA macro { ( ((a4h==2)&(a19.pin==1))#(a4h==3)#(a4h==4)#(a4h==5)#(a4h==6)#(a4h==7)#(a4h==8)#(a4h==9) ) } //7.5 meg from $28.0000 - $9f.ffff @ifdef v40 {v4x = 1;} @ifdef v42 {v4x = 1;} @ifdef v5x {v5x6x=1;} @ifdef v6x {v5x6x=1;} //for pcb v42, pins 85,81 must not drive/prg-gnd (because connected to same signals as pins 99, 22) //for pcb v40 code to work on pcb v42, pins 99, 22 must not drive/programmed ground. //"v4x5volt" cpld code for xc9572-tq100, settings: speedgrade -15, locations constraints always, optimize speed, slow slew, powerup registers low, no global pin use, macrocell low power, NOW YES instead of no programmable grounds, pin feedback off //compatible pcb v40,42,43. 7M and reset only at 1 pins //v42 3volt3 : //On pcb 42,43: 7M, rst have two pins each to choose from //xc9572xl-tq100 settings - bushold on, speed grade -10, like above, use global clock, global reset. XL has no pinfeedback option //pcb v5x, and pcb v6x: //xc9572xl-vq64, settings -7 speed grade. global clock and reset. unused pins programmable grounds off //vplcc128x: //xcr3128xl-vq100 plcc 1287 version, pullup unused io, -10 speed grade, timing + location constraints, slow slew, powerup registers low, reserve isp pins on //start PIN DEFINITIONS, with reset, clk, ... cpu pins cpu_nreset, cpu_clk, cpu_r_w, cpu_nuds, cpu_nlds, cpu_nas pin @ifdef v5x6x {64,16,10,13,15,12} @ifdef v40 {85,81,86,94,87,95} @ifdef v42 {99,22,86,94,87,95} @ifdef vplcc128x {87,88,98,99,89,90} ; clock = cpu_clk.pin; reset = !cpu_nreset.pin; //This seemed to consume the macrocells? //low driven pins //todo: find way to use programmed grounds setting without grounding pins that must not be driven //@ifdef v4x {//output a '0' to grounded pins or unconnected pins //declarations p3,p23,p30,p32,p33,p36,p37,p40,p42,p49,p89,p90,p91,p92,p93 pin 3,23,30,32,33,36,37,40,42,49,89,90,91,92,93; //equations p3=0;p23=0;p30=0;p32=0;p33=0;p36=0;p37=0;p40=0;p42=0;p49=0;p89=0;p90=0;p91=0;p92=0;p93=0; //declarations //} //This seemed to take a few rounds with exhaustive fit mode before finding a fit //For programmable grounds, hack a read-out term consisting of reserverd i/o(=not to be driven by cpld) that webpack 4.2 doesn't optimise out @ifdef v42 { declarations spr1 pin 14; //output to this spare pin termnode node istype 'com'; p85,p81 pin 85,81; equations termnode = p85.pin # p81.pin; //on V42, pin 85 is another active low reset pin besides pin 99. => after reset termnode = '1' //use termnode somewhere to output spr1 = termnode; //spare pin 1 should go high after reset or during clock high declarations } //@ifdef v40 //{ //declarations // spr1 pin 14; //equations // spr1 = '1'; //declarations //} // notusednowcodemaybebroken:@ifdef v4x { // spr2 pin 12; // spr2readreg node istype 'reg'; // // equations // //sparepin 1 spr1 should be high after reset # during clock high, or v40 always // spr2readreg.aclr = reset; // spr2readreg.clk = !cpu_nas.pin; //cpu activity triggers read pin // spr2readreg := spr2.pin # spr2readreg.fb; //spr2 low or high, may not float // ramonjumpered = spr2readreg.fb; // declarations // } //address, data, cpu control, dram control a23..a1 pin @ifdef v5x6x {47,46,45,44,43,42,40,39,38,36,35,34,33,32,31,27,25,24,23,20,19,18,17} @ifdef v4x {54,53,52,50,39,41,35,29,27,25,18,17,16,15,13,11,10,9,6,4,1,96,97} @ifdef vplcc128x {36,41,44,45,46,47,48,49,50,55,60,61,63,64,65,67,68,72,76,79,80,81,83} ; //some address bits are don't cares for autoconfig address comparator aconfaddr = [a23.pin, a22.pin, a21.pin, a20.pin, a19.pin, a18.pin, a17.pin, a16.pin, .x., .x., .x., .x., .x., .x., .x., .x., .x., a6.pin,a5.pin,a4.pin,a3.pin,a2.pin,a1.pin,.x.]; d15..d12 pin @ifdef v5x6x { 48,49,50,51} @ifdef v4x { 66,67,68,70} @ifdef vplcc128x {33,31,29,23} ; ma11..ma0 pin @ifdef v5x6x {60,59,58,57,56,52,9,8,7,6,5,4} @ifdef v4x {61,60,59,58,55,56,79,78,76,77,74,82} @ifdef vplcc128x {53,56,52,54,57,58,71,70,69,75,77,78} ; !ras, !ucas, !lcas, !ramoe, !ramwr pin @ifdef v5x6x {2,62,63,61,1} @ifdef v4x {72,64,65,63,71} @ifdef vplcc128x {84,40,37,42,85} ; @ifdef v4x {!led_on pin 8;} @ifdef v5x {!bufena pin 11 istype 'com';} @ifdef use_autoconfig_logic { //AUTOCONFIG(TM) declarations //config in/out pins @ifdef v4x { config_nin pin 28; config_nout pin 20 istype 'com'; } @ifdef v6x { config_nin pin 11; config_nout pin 22 istype 'com'; } @ifdef vplcc128x { config_nin pin 96; config_nout pin 25 istype 'com'; //this was wrong (pin 20) in 14.8.2017 version } //v5x pin 22 either config in or out @ifdef v5x { @ifdef v5xconfigout {config_nout pin 22;} @ifdef v5xconfigin { config_nout node istype 'com';//node only, no output config_nin pin 22;} } //synchronise pin input to clock, (and thus cpu_nas(?)) @ifdef config_nin { declarations config_in_signal node istype 'com'; sn0, sn1 node istype 'reg'; equations sn0.clk = clock; sn0.aclr = reset; sn1.clk = clock; sn1.aclr = reset; sn0 := !config_nin.pin; sn1 := sn0.fb; config_in_signal= sn1.fb; } @ifndef config_nin {declarations config_in_signal = @ifndef force_config_after_one_other {1} @ifdef force_config_after_one_other {0} ;} // autoconfig cycle off -> (skip 1) -> try offer 8meg, 4 meg, 2meg, 1meg-> off (result shutups or ram configured) declarations acdi = [d15..d12].pin; //autoconfig data in sza3,sza2,sza1,sza0 node istype 'com'; sizeacdo = [sza3..sza0]; pnz3,pnz2,pnz1,pnz0 node istype 'com'; product_number_lowbits = [pnz3..pnz0]; //output certain data at autoconfig //8meg to 200000..9fffff //4meg to 2meg boundary //2meg to 2meg boundary //1meg to 1meg boundary //4.10.2018 change from 2 meg to 1 meg blocks ramblock2 node istype 'reg'; //ram at 200000..2fffff configured ramblock3 node istype 'reg'; ramblock4 node istype 'reg'; //..so on ramblock5 node istype 'reg'; ramblock6 node istype 'reg'; ramblock7 node istype 'reg'; ramblock8 node istype 'reg'; ramblock9 node istype 'reg'; ramblocks = [ramblock2,ramblock3,ramblock4,ramblock5,ramblock6,ramblock7,ramblock8,ramblock9]; stat2..stat0 node istype 'reg'; autoconfig_state = [stat2..stat0]; notstarted= [0,0,0]; //reseted state // skipone = [1,0,0]; //changed skip one autoconfig cycle style offer8meg = [1,0,0]; offer4meg = [1,0,1]; offer2meg = [1,1,1]; offer1meg = [1,1,0]; autoconfig_finished = [0,1,0]; ist0 = [0,0,1]; ist1 = [0,1,1]; autoconfig_shutup = (cpu_r_w.pin == '0') & (aconfaddr == ^hE8004C); autoconfig_assign = (cpu_r_w.pin == '0') & (aconfaddr == ^hE80048); equations ramblocks.aclr =reset; ramblocks.clk = cpu_nas.pin; autoconfig_state.clk = cpu_nas.pin; autoconfig_state.aclr = reset; state_diagram autoconfig_state; state ist0: goto ist0; //these shouldn't happen state ist1: goto ist1; state notstarted: sizeacdo = [.x.,.x.,.x.,.x.]; //dont cares product_number_lowbits = [.x.,.x.,.x.,.x.]; //dont cares ramblocks := [0,0,0,0,0,0,0,0]; if ( (config_in_signal == '1') @ifdef force_config_after_one_other { # (autoconfig_assign # autoconfig_shutup) } ) then @ifdef skipoffer8megs {offer4meg} @ifndef skipoffer8megs {offer8meg} else notstarted; // Older style skip one autoconfig cycle state skipone: // sizeacdo = [.x.,.x.,.x.,.x.]; //dont cares // product_number_lowbits = [.x.,.x.,.x.,.x.]; //dont cares // ramblocks := [0,0,0,0,0,0,0,0]; // if (autoconfig_assign # autoconfig_shutup) // then @ifdef skipoffer8megs {offer4meg} // @ifndef skipoffer8megs {offer8meg} // else skipone; state offer8meg: sizeacdo = [0,0,0,0]; // 000 for 8mb product_number_lowbits = 8; //show megs as card's product number for diagnostisism if (autoconfig_shutup) then offer4meg with ramblocks:=[0,0,0,0,0,0,0,0] else if (autoconfig_assign) then autoconfig_finished with ramblocks:=[1,1,1,1,1,1,1,1] //8 megs can go to 20.0000-9f.ffff hex else offer8meg with ramblocks := ramblocks.fb; state offer4meg: sizeacdo = [0,1,1,1]; // 111 for 4mb product_number_lowbits = 4; //show megs as card's product number for diagnostisism if (autoconfig_shutup) then offer2meg with ramblocks:=[0,0,0,0,0,0,0,0]; else if (autoconfig_assign) then offer2meg with { //4 megs can start at 20.0000, 40.0000 or 60.0000 hex ramblock2 := (acdi==2); ramblock3 := (acdi==2); ramblock4 := (acdi==2) # (acdi==4); ramblock5 := (acdi==2) # (acdi==4); ramblock6 := (acdi==4) # (acdi==6); ramblock7 := (acdi==4) # (acdi==6); ramblock8 := (acdi==6); ramblock9 := (acdi==6); } else offer4meg with ramblocks:=ramblocks.fb; state offer2meg: sizeacdo = [0,1,1,0]; //0110 for 2mb product_number_lowbits = 2; //show megs as card's product number for diagnostisism if (autoconfig_shutup) then autoconfig_finished with ramblocks:=ramblocks.fb else if (autoconfig_assign) then autoconfig_finished with { ramblock2 := (acdi==2) # ramblock2.fb; ramblock3 := (acdi==2) # ramblock3.fb; ramblock4 := (acdi==4) # ramblock4.fb; ramblock5 := (acdi==4) # ramblock5.fb; ramblock6 := (acdi==6) # ramblock6.fb; ramblock7 := (acdi==6) # ramblock7.fb; ramblock8 := (acdi==8) # ramblock8.fb; ramblock9 := (acdi==8) # ramblock9.fb; } else offer2meg with ramblocks:=ramblocks.fb; state offer1meg: sizeacdo = [0,1,0,1]; //0101 for 1mb product_number_lowbits = 1; //show megs as card's product number for diagnostisism if (autoconfig_shutup) then autoconfig_finished with ramblocks:=ramblocks.fb else if (autoconfig_assign) then autoconfig_finished with { ramblock2 := (acdi==2) # ramblock2.fb; ramblock3 := (acdi==3) # ramblock3.fb; ramblock4 := (acdi==4) # ramblock4.fb; ramblock5 := (acdi==5) # ramblock5.fb; ramblock6 := (acdi==6) # ramblock6.fb; ramblock7 := (acdi==7) # ramblock7.fb; ramblock8 := (acdi==8) # ramblock8.fb; ramblock9 := (acdi==9) # ramblock9.fb; } else offer1meg with ramblocks:=ramblocks.fb; state autoconfig_finished: sizeacdo = [.x.,.x.,.x.,.x.]; product_number_lowbits = [.x.,.x.,.x.,.x.]; //dont cares ramblocks := ramblocks.fb; //hold until next reset goto autoconfig_finished; declarations config_out_1 node istype 'reg'; config_out_2 node istype 'reg'; equations config_out_1.aclr = reset; config_out_1.clk = clock; config_out_2.aclr = reset; config_out_2.clk = !clock; config_out_1 := autoconfig_state.fb == autoconfig_finished; //Delay for autoconfig-out to allow zorro-Address_Strobe finished. clock down (to S1) <- clock up (to S0) <- after /AS up (in S7) after going to finish state config_out_2 := config_out_1.fb; config_nout = !config_out_2.fb; // autoconfig data forming declarations //sets autodata15..autodata12 node istype 'com'; acdo = [autodata15..autodata12]; //autoconfig data out equations when (aconfaddr==^hE80000) then acdo = [1,1,1,0]; else when (aconfaddr==^hE80002) then acdo = sizeacdo; //8/4/2/1 meg else when (aconfaddr==^hE80004) then acdo = ^hf; //prod.num high bits complemented 0 else when (aconfaddr==^hE80006) then acdo = [!product_number_lowbits[3],!product_number_lowbits[2],!product_number_lowbits[1],!product_number_lowbits[0]]; else when (aconfaddr==^hE80008) then acdo = 7; //bit 6=='0' means board can shut up (=> complemented bit2 of $e80008 == '1') else when (aconfaddr==^hE8000A) then acdo = ^hF; else when (aconfaddr==^hE80010) then acdo = ^hE; else when (aconfaddr==^hE80012) then acdo = ^hE; else when (aconfaddr==^hE80014) then acdo = ^hE; else when (aconfaddr==^hE80016) then acdo = ^hE; else when (aconfaddr==^hE80040) then acdo = 0; else when (aconfaddr==^hE80042) then acdo = 0; else acdo = [1,1,1,1]; // out autoconfig data (E8xxxx) declarations autoconfig_respond = (autoconfig_state.fb == offer8meg) # (autoconfig_state.fb == offer4meg) # (autoconfig_state.fb == offer2meg) # (autoconfig_state.fb == offer1meg); acdo_enable= (cpu_r_w.pin & !cpu_nuds.pin & ([a23..a16].pin == ^hE8) & autoconfig_respond); equations @ifndef vplcc128x {//for vplcc128x, data out code below [d15..d12]=acdo; [d15..d12].oe=acdo_enable;} }//end @if use_autoconfig_logic equations @ifdef led_on { led_on = config_out_2.fb; } //DRAM declarations a4h = [a23,a22,a21,a20].pin; //1meg blocks ah2 = (a4h == 2); ah3 = (a4h == 3); ah4 = (a4h == 4); ah5 = (a4h == 5); ah6 = (a4h == 6); ah7 = (a4h == 7); ah8 = (a4h == 8); ah9 = (a4h == 9); // EQUATIONS // address comparator of mem selection mem_selected = @ifdef use_ARRA {ARRA} @ifdef use_ARRA {@ifdef use_autoconfig_logic {#}} @ifdef use_autoconfig_logic {(ah2 & ramblock2.fb) # (ah3 & ramblock3.fb) # (ah4 & ramblock4.fb) # (ah5 & ramblock5.fb) # (ah6 & ramblock6.fb) # (ah7 & ramblock7.fb) # (ah8 & ramblock8.fb) # (ah9 & ramblock9.fb)} ; //*************************************************** //clock high to state2, as asserted 3-60 nS //clock low to s7, as negated -..62 nS (8MHZ cpu) 3..25(20MHz cpu) //interrupt cycles have high address =111111... when nas, no int cycle at ram addr //*************************************************** // normal cycle generator declarations dly_as node istype 'reg'; access_ras, access_casu, access_casl, mux_switch_column_address node istype 'reg'; rfsh_cas node istype 'reg'; rfsh_ras_r node istype 'reg'; rfsh_ras node istype 'com'; equations //68000 S0->S1 (or no bus cycle) refresh cas, S2 refresh ras, s3 both off by 68k AS or toggle off if no bus cycle for clock hi, clock lo period and repeat refresh //S4 access ras signal, going to s5 switch address mux, S6 access cas, during S7 asynch clear access cas and ras // cas before ras refresh cycle generator //CAS set-up time (CAS -before-RAS refresh) tCSR 5 5 ns 17 //CAS hold time (CAS -before-RAS refresh) tCHR 10 10 ns //CAS to RAS precharge time tCRP 5 5 ns //CAS precharge time (Hyper page cycle) tCP 8 10 ns 14 //access-cas negate in state7 to refresh-cas assert 10ns min (and gate etc delays //RAS precharge time tRP 30 40 ns //state7 negates as and thus ras //121 Clock Low to AS, DS Negated — 62 — 50 — 40 — 40 3 30 3 25 ns //cpu clock falling from state 6 low to state 7 negates as in --(0?)..62 ns (parameter 12) //cpu clock rising high from state 1 to state 2 asserts as in 3..60 ns (parameter 9'9 rfsh_cas.clk = !clock; //no asynch set/reset fot rfsh_cas rfsh_cas := !rfsh_cas.fb & cpu_nas.pin; //0 when AS asserted at clock fall // rfsh_cas_on toggles on in S1, because as negated in s7 and s0. and rfsh_cas negates going to s3, since as asserted in s2 // if no cpu cycle, as stays negated until s2, and rfsh cas in s3 rfsh_ras_r.clk = clock; rfsh_ras_r := rfsh_cas.fb; ////23.9.2018 version: rfsh_ras = rfsh_cas.fb & clock; ////Chance of race glitch if "clock" high still high in latter part while rfsh_cas go up at falling clock? rfsh_ras = rfsh_ras_r.fb & rfsh_cas.fb; //refresh ras asserted while in high clock half (s2). both ras and cas negated in s3, refresh cas not asserted in s4 cause as asserted //rfsh cas, no rfsh ras, no rfsh cas, no rfsh ras, rfsh cas, no rfsh cas, rfsh cas and ras... when no cpu cycles // output signals generator //access_ras with entering S4, turn off in S7, trough S0,S1, some part of S2 //rfsh_cas in s2 ras = access_ras.fb # rfsh_ras; //access_cas with entering S6, turn off in S7, through S0,S1, some part of S2 ? //rfsh_cas.fb on entering S1 /// ucas = ((cpu_nuds.pin=='0') & access_cas.fb) # rfsh_cas.fb; /// lcas = ((cpu_nlds.pin=='0') & access_cas.fb) # rfsh_cas.fb; ucas = access_casu.fb # rfsh_cas.fb; lcas = access_casl.fb # rfsh_cas.fb; //Output buffer turn off delay time from OE tOEZ 3 - 13 ramoe = (cpu_r_w.pin == '1') & (!cpu_nuds.pin # !cpu_nlds.pin) & mem_selected; ramwr = (cpu_r_w.pin == '0') & (!cpu_nuds.pin # !cpu_nlds.pin) & mem_selected; //ramwr and data to ram must be valid by cas - ramwr negated in refresh cas //cpld clock is close to cpu clock dly_as.clk = !clock; dly_as := !cpu_nas.pin; //at clock fall to state S3 assert by AS asserted in state S2 dly_as.aclr = cpu_nas.pin; //negated by AS negated during S7 access_ras.clk = clock; access_ras := dly_as.fb & mem_selected; //assert by clock rise to S4. Row address muxed to during S2 by AS access_ras.aclr = cpu_nas.pin; //negated by AS negated during S7 - AS negated -..62 ns after clock fall, asynch. terminates access_ras,cas access_casu.clk = clock; access_casu := access_ras.fb & !cpu_nuds.pin; //assert with clock rise to S6. Column address muxed to dram entering S5 access_casu.aclr = cpu_nas.pin; //negate during S7 access_casl.clk = clock; access_casl := access_ras.fb & !cpu_nlds.pin; //assert with clock rise to S6. Column address muxed to dram entering S5 access_casl.aclr = cpu_nas.pin; //negate during S7 //notes //lds,uds assert on _write_ at s4, on _read_ at s2 - data, column address and r/w should be valid when cas asserted //READ DATA from dram latched to 68000 entering state7 clock fall (70ns, tcac=20ns) //write data from 68000 removed at databus rising clock from s7 to 0 and drives r/w high @ifdef bufena { equations bufena = (!cpu_nuds.pin # !cpu_nlds.pin) & mem_selected; //now mem_selected includes "ram on" gating } @ifdef vplcc128x { //cpld data buffers declarations //dram data bus dd15..dd0 pin 19,22,27,24,28,30,32,35,92,93,94,97,100,9,8,7 istype 'com'; //cpu d12..0 d11..d0 pin 21,20,17,16,14,13,12,10,6,5,2,1 istype 'com'; equations [dd15..dd0]=[d15..d0].pin; [dd15..dd8].oe = !cpu_r_w.pin & !cpu_nuds.pin & mem_selected; [dd7..dd0].oe = !cpu_r_w.pin & !cpu_nlds.pin & mem_selected; [d7..d0]=[dd7..dd0].pin; [d7..d0].oe = cpu_r_w & !cpu_nlds.pin & mem_selected; [d11..d8]=[dd11..dd8].pin; [d11..d8].oe = cpu_r_w & !cpu_nuds.pin & mem_selected; //AUTOCONFIG DATA out when (mem_selected) then { [d15..d12] = [dd15..dd12].pin; [d15..d12].oe = cpu_r_w & !cpu_nuds.pin; } else { [d15..d12] = acdo; [d15..d12].oe = acdo_enable; } } // address MUX switcher generator mux_switch_column_address.clk = !clock; //clocked at falling edge of cpu/cpld clock mux_switch_column_address := access_ras.fb; // set to 1 on negedge(S5) after beginning of access_ras(S4) (put out column address) mux_switch_column_address.aclr = cpu_nas.pin; // reset to 0 (during state7, through state0, state1, off at S2) // DRAM MAx (daxx) multiplexor (todo: with refresh row count) declarations //ras only refresh / row count not implemented rac11..rac0 node istype 'com'; equations [rac11..rac0] = [0,0, 0,0 ,0,0 ,0,0 ,0,0 ,0,0]; when !((cpu_nas.pin=='0') & mem_selected) then @ifdef xc9500xl { //using bus hold with xc9500xl parts [ma11..ma0].oe = !cpu_nas.pin; } @ifndef xc9500xl { [ma11..ma0] = [rac11..rac0]; } else when (mux_switch_column_address.fb == '1') then {ma11=0; ma10=0; [ma9..ma0] = [a10..a1].pin; } else [ma11..ma0] = [a22..a11].pin; //RAS only REFRESH with refresh row counter? //DECLARATIONS // rac11..rac0 node istype 'reg'; // lsk1..lsk2 node istype 'reg'; //EQUATIONS // when nextrac // rac := rac.fb + 1; // else rac := rac.fb; //EQUATIONS //DECLARATIONS // cnt1..cnt0 node istype 'reg'; // rfsh_cnt = [cnt1..cnt0]; //EQUATIONS // rfsh_cnt.clk =; // rfsh_cnt.aclr = reset; // rfsh_cnt := rfsh_cnt.fb + 1; "w,oe,ras,ucas,lcas "!as -> da='111... "0 as -> da=a21.. "as ->viive0ns -> ras "ras->viive10ns->da=lo "ras to cas 45 ns "da=lo ->0ns -> cas (u,l) "10 ns, "s0-s1:fc, ei w mutta r, ei a "s1-s2:a "s2-s3:as, write data (r,uds lds) "s3-s4:d "s4-s5:uds,lds (dtack) "s5-s6 "s6-s7 dataa sisaan, "s7-s0:ei as, ei uds, ei lds, ei d, "s0-s1:ei a, ei w, fc "read modify write: tas, not on amiga (not on CHIP ram?) END