Altera Code for 8-bit Input/Output Port
SUBDESIGN ea_io ( E : INPUT; % E-Clock % R_W : INPUT; % R/W Line % RESETn : INPUT; % Reset line % PA[7..0] : BIDIR; % Address and Data (15-8) from HC12 % PB[7..0] : BIDIR; % Address and Data (7-0) from HC12 % EA[7..0] : BIDIR; % Expansion Port A % ) VARIABLE demux[15..0] : DFF; % Demuliplexed address internal % IDB[7..0] : NODE; % Internal data bus % EAI[7..0] : DFFE; % Internal expansion Port A register % CTRLE0 : DFFE; % Bit to make EA an output port (DDRA bit) % PA_OE : NODE; % High when we want to send data to HC12 on % % the HC12's Port A % BEGIN % ***********************************************************************% % Address decoding and demultiplexing % % Latch address on rising edge of E clock % % ***********************************************************************% demux[15..8].d = PA[7..0]; demux[7..0].d = PB[7..0]; demux[15..0].clk = E; % ***********************************************************************% % Start of expansion ports % % ***********************************************************************% % A write to address 0x0400 writes to the internal EA flip flops % % Writes take place on the falling edge of E clock % EAI[].clk = !E; EAI[].ena = (demux[15..0].q == H"0400") & (R_W == GND); EAI[].d = PA[]; EAI[].clrn = RESETn; % A write to address 0x0402 writes to expansion control register % CTRLE0.clk = !E; CTRLE0.ena = (demux[15..0].q == H"0402") & (R_W == GND); CTRLE0.d = PA0; CTRLE0.clrn = RESETn; % If Bit 0 of CTRLE is 1, EA is an output port; drive data from the % % internal register onto the EA lines % % If Bit 0 of CTRLE is 0, EA reads data from outside % EA[7] = TRI(EAI[7], CTRLE0); EA[6] = TRI(EAI[6], CTRLE0); EA[5] = TRI(EAI[5], CTRLE0); EA[4] = TRI(EAI[4], CTRLE0); EA[3] = TRI(EAI[3], CTRLE0); EA[2] = TRI(EAI[2], CTRLE0); EA[1] = TRI(EAI[1], CTRLE0); EA[0] = TRI(EAI[0], CTRLE0); % A read from address 0x0400 reads the expansion port A % % A read from address 0x0402 reads the expansion control register % % Put the data from the expansion ports or control regiser onto the % % internal data bus Otherwise, put 0x00 onto the internal data bus % IF (demux[15..0].q == H"0400") THEN IDB[7..0] = EA[7..0]; ELSIF (demux[15..0].q == H"0402") THEN IDB[7..1] = 0; IDB[0] = CTRLE0.q; ELSE IDB[7..0] = H"0000"; END IF; % If reading from address 0x0400 or 0x0402, we need to drive the % % Port A lines when E is high % IF (R_W==VCC) & (E == VCC) & ((demux[15..0].q == H"0400") # (demux[15..0].q == H"0402")) THEN PA_OE = VCC; ELSE PA_OE = GND; END IF; % Here's where we put the internal data bus values onto Port A % PA[7] = TRI(IDB[7], PA_OE); PA[6] = TRI(IDB[6], PA_OE); PA[5] = TRI(IDB[5], PA_OE); PA[4] = TRI(IDB[4], PA_OE); PA[3] = TRI(IDB[3], PA_OE); PA[2] = TRI(IDB[2], PA_OE); PA[1] = TRI(IDB[1], PA_OE); PA[0] = TRI(IDB[0], PA_OE); END;