MODULE mem68k "converted from LordV A600 4 chip 8 meg memory cpld verilog code to abel code for single 4M x 16 chip "3.3v hm5165165 tsop-50, 5v KM416C4104C 4K_refresh, column select to aa0..aa9, row select to aa0..aa11. 3.3 volt hy... chip //pins 85 and 81 not to be made programmable grounds for pcb v42, v40 //pins 99 and 22 not to be made programmable grounds for pcb v42 //so this abel is uses trick not to optimise away these pins for v40 or v42 with xilinx ise 4.2. "13.8.2017 pin numbers for vqfp64 version v58, 14.8.2017 pin numbers for plcc xcr3128xl version "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 //V40 option should be made to work with v42 too. "v40 =1; //xc9572-tq100, speedgrade -15, locations constraints always, optimize speed, slow slew, powerup registers low, no global pin use, macrocell low power, programmable grounds, pin feedback off //14.8.2017 v40 user code "40a1" v42 =1; //tqfp100 xc9572/xc9572xl //14.8.2017 v42 user code "42a1" xc9572xl-tq100 - bushold on, speed grade -10, like above, use global clock, global reset. XL has no pinfeedback option "v5x =1; //xc9572xl-vq64 //14.8.2017 v58 user code "58a1" xc9572xl-vq64, -7 speed grade. global clock and reset. unused pins programmable grounds should not matter, no unused pins. "vplcc128x = 1; //xcr3128xl-vq100 //14.8.2017 plcc 1287 version user code "p1a1" , pullup unused io, -10 speed grade, timing + location constraints, slow slew, powerup registers low, reserve isp pins on @ifdef v40 {v4x = 1;} @ifdef v42 {v4x = 1;} a23..a1 pin @ifdef v5x {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} ; d15..d12 pin @ifdef v5x { 48,49,50,51} @ifdef v4x { 66,67,68,70} @ifdef vplcc128x {33,31,29,23} ; da11..da0 pin @ifdef v5x {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} ; cpu_nreset, cpu_clk, cpu_r_w, cpu_nuds, cpu_nlds, cpu_nas pin @ifdef v5x {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} ; declarations clock = cpu_clk.pin; reset = !cpu_nreset.pin; @ifdef v5x {!bufena pin 11 istype 'com';} !ras, !ucas, !lcas, !ramoe, !ramwr pin @ifdef v5x { 2,62,63,61,1} @ifdef v4x { 72,64,65,63,71} @ifdef vplcc128x {84,40,37,42,85} ; config_nout pin @ifdef v5x {22} @ifdef v4x {20} @ifdef vplcc128x {20} istype 'com'; @ifdef vplcc128x {config_nin pin 96}; @ifdef v4x {config_nin pin 28;} @ifdef v4x { led_out pin 8;} //for pcb v42, pins 85,81 must float (connected to same signals as pins 99, 22) //for pcb v40 code to work on pcb v42, pins 99, 22 must float //prevent optimizing out the input pins in order not to make them programmable grounds @ifdef v40 {unused1, unused2 pin 99,22;} @ifdef v42 {unused1, unused2 pin 85,81;} //pin49 free not connected in v40 @ifdef v40 {jee pin 49 istype 'com';} @ifdef v42 {jee node;} //the other unused being !reset, other clock, during reset jee = !clock, no reset: jee= 0 @ifdef v4x {equations jee = !unused1.pin & !unused2.pin; declarations } @ifdef v4x { spare1, spare2 pin 14,12; equations spare2='0'; } @ifdef v42 {spare1 = jee;} @ifdef v40 {spare1 = '0';} declarations dly_as node istype 'reg'; equations dly_as.aclr = cpu_nas.pin; dly_as.clk = !clock; "falling edge (nas assert 62ns max from clock rise?, negate ?) 7,16 MHz cycle 140ns (/2 =70ns) dly_as := !cpu_nas.pin; declarations "nodes mem_selected node istype 'com'; access_ras, access_cas, mux_switch_column_address node istype 'reg'; rfsh_cas node istype 'reg'; rfsh_ras node istype 'com'; "autoconfig synch0, synch1 node istype 'reg'; autoconfig_started node istype 'reg'; autoconfig_done node istype 'reg'; ah = [a23,a22,a21,a20].pin; "set EQUATIONS "// chip selector decoder "2xxxxx..9xxxxx=> 001x 010x 011x 100x mem_selected = (ah==2)#(ah==3)#(ah==4)#(ah==5)#(ah==6)#(ah==7)#(ah==8)#(ah==9); "*************************************************** "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 "previous clock up, if AS negated, was entering state2 (clock low enters s3). if AS now (rising clock) then asserted, it is state4 "lds,uds assert on _write_ at s4 access_ras.clk = clock; access_ras.aclr = cpu_nas.pin; "as negated -..62 ns after clock fall, asynch. terminates access_ras,cas access_cas.clk = clock; access_cas.aclr = cpu_nas.pin; "access_ras with state4, row address (gated by AS) at dram, at state2 or 3, also r/w low to dram /rw Data set-up time tDS 0 nS Data hold time tDH 10 ns // access_ras := !dly_nas.pin & mem_selected & autoconfig_done.fb; "glitch from invalid address bus? address strobe should gate it off? // dly_as vs. !cpu_nas.pin: clock rise to cpu_nas 3-62ns? access_ras := dly_as.fb & mem_selected & autoconfig_done.fb; access_cas := access_ras.fb; "goes '1' at next clock after access_ras state 6. Column address at dram after entering s5 by cpu clock going low) "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 & autoconfig_done.fb; } @ifdef plccv128x { "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'; bufon node istype 'com'; equations bufon = (!cpu_nuds.pin # !cpu_nlds.pin) & mem_selected & autoconfig_done.fb; [dd15..dd0]=[d15..d0].pin; [dd15..dd8].oe = !cpu_rnw.pin & !cpu_nuds.pin & bufon; [dd7..dd0].oe = !cpu_rnw.pin & !cpu_nlds.pin & bufon; [d7..d0]=[dd7..dd0].pin; [d7..d0].oe = cpu_rnw & !cpu_nlds_pin & bufon; [d11..d8]=[dd11..dd0].pin; [d11..d8].oe = cpu_rnw & !cpu_nuds.pin & bufon; when (!memselected) [d15..d12] = acdo; else [d15..d12] = [dd15..dd12].pin; [d15..d12].oe = (cpu_rnw & !cpu_nuds.pin & bufon) # autonfig_d1512_output_enable; } "// MUX switcher generator mux_switch_column_address.aclr = reset; 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 after beginning of access_ras (put out column address) //returns to 0 by access_ras gone 0 by async reset by as high after cpu clock going low to state s7, falling clock to state s1 -- x nS from clock low to s7 to as negated???? // DRAM MAx (daxx) multiplexor with refresh row count declarations "ras only refresh / row count not implemented rac11..rac0 node istype 'com'; equations [rac11..rac0] = [1,1, 1,1 ,1,1 ,1,1 ,1,1 ,1,1]; when !( (cpu_nas.pin=='0') & mem_selected & autoconfig_done.fb) then [da11..da0] = [rac11..rac0]; else when (mux_switch_column_address.fb == '1') then {da11=0; da10=0; [da9..da0] = [a10..a1].pin; } else [da11..da0] = [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 "// cas before ras refresh cycle generator "DECLARATIONS " cnt1..cnt0 node istype 'reg'; " rfsh_cnt = [cnt1..cnt0]; "EQUATIONS " rfsh_cnt.clk =; " rfsh_cnt.aclr = reset; " rfsh_cnt := rfsh_cnt.fb + 1; "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 "121 Clock Low to AS, DS Negated — 62 — 50 — 40 — 40 3 30 3 25 ns rfsh_cas.clk = !clock; "neg. edge cpu clock (when as negated...) rfsh_cas.aclr = !cpu_nas.pin; " async reset when as asserted "could use delayed cpu_nas, 3 ns hold is little rfsh_cas := !rfsh_cas.fb & (cpu_nas.pin); "TOGGLES?? while no AS rfsh_ras = rfsh_cas.fb & clock; "// output signals generator ras = access_ras.fb # rfsh_ras; ucas = ((cpu_nuds.pin=='0') & access_cas.fb) # rfsh_cas.fb; lcas = ((cpu_nlds.pin=='0') & access_cas.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 & autoconfig_done.fb; ramwr = (cpu_r_w.pin == '0') & (!cpu_nuds.pin # !cpu_nlds.pin) & mem_selected & autoconfig_done.fb; "ramwr and data to ram must be valid by cas "// autoconfig data forming declarations "sets la = [a6.pin,a5.pin,a4.pin,a3.pin,a2.pin,a1.pin,.x.]; autodata15..autodata12 node istype 'com'; acdo = [autodata15..autodata12]; equations when (la==0) then acdo = [1,1,1,0]; else when (la==2) then acdo = [0,0,0,0]; "// 0111 for 4mb, 0000 for 8mb else when (la==4) then acdo = ^hE; else when (la==6) then acdo = ^hE; else when (la==8) then acdo = 3; else when (la==^h0A) then acdo = ^hF; else when (la==^h10) then acdo = ^hE; else when (la==^h12) then acdo = ^hE; else when (la==^h14) then acdo = ^hE; else when (la==^h16) then acdo = ^hE; else when (la==^h40) then acdo = 0; else when (la==^h42) then acdo = 0; else acdo = [1,1,1,1]; // out autoconfig data (E8xxxx) declarations acdo_enable node istype 'com'; equations acdo_enable= (cpu_r_w.pin & !cpu_nuds.pin & ([a23..a16].pin == ^hE8) & autoconfig_started.fb & !autoconfig_done.fb); [d15..d12]=acdo; [d15..d12].oe=acdo_enable; // autoconfig cycle off -> on -> off autoconfig_started.clk = clock; autoconfig_started.aclr = reset; @ifdef config_nin { synch0.clk = clock; synch0.aclr = reset; synch1.clk = clock; synch1.aclr = reset; synch0 := !config_nin.pin; synch1 := synch0.fb; when (synch1.fb == '1') then autoconfig_started := '1'; else autoconfig_started := autoconfig_started.fb; "hold } @ifndef config_nin { autoconfig_started := '1'; "no config in input to use } equations autoconfig_done.aclr = reset; autoconfig_done.clk = cpu_nas.pin; "rising edge clocks when (!cpu_r_w.pin & ([a23..a16].pin == ^hE8) & ([a6..a3].pin == [1,0,0,1]) & autoconfig_started.fb) // write at $E80048..$E8004E then autoconfig_done := '1'; else autoconfig_done := autoconfig_done.fb; "hold config_nout = !autoconfig_done.fb; @ifdef led_out { led_out = !autoconfig_done.fb; led_out = '0'; "sink current (cathode end of led) led_out.oe = autoconfig_done.fb; "light up led } "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, data sisaan "s0-s1:ei a, ei w, fc "read modify write: tas, not on amiga END