Memory Mapped IO - red-bote/VHDL_Demos GitHub Wiki

The VHDL project demonstrates Memory mapped output to LEDs with VHDL T80 simulation.

A Single-Port BRAM Read-First Mode is incorporated into the project, it is defined with storage array size of 1024 bytes.

The Single-Port RAM with Read First (VHDL) is described in Vivado Design Suite User Guide (UG901).

UG901 is a registered download

Output Latch

Memory mapped 4-bit Latch with Inverted Gate and Asynchronous Set combined to make an 8-bit output.

Control signals equivalent to writing a RAM, partial address decode 0x5100 and 0x5101.

    ram_wr_en <= not (cpu_wr_l or cpu_mreq_l);
    outp_enable <= '0' when cpu_addr(15 downto 12) = "0101" and ram_wr_en = '1' else '1';
    outp_gate_0_l <= (outp_enable or cpu_addr(0));
    outp_gate_1_l <= (outp_enable or not cpu_addr(0));

    u_outp0 : entity work.latches_3
    port map (
        D => cpu_data_out(3 downto 0),
        G => outp_gate_0_l, -- Inverted Gate 
        PRE => reset,
        Q => outp_dout_0
    );
    u_outp1 : entity work.latches_3
    port map (
        D => cpu_data_out(7 downto 4),
        G => outp_gate_1_l, -- Inverted Gate 
        PRE => reset,
        Q => outp_dout_1
    );

Latches are generally to be avoided:

[Synth 8-327] inferring latch for variable 'Q_reg' ["/home/xubuntu/hdl/VHDL_Demos/cpu/t80_io/t80_io.srcs/sources_1/imports/latches/latches_3.vhd":21]

images/T80_IO/HL9sb7.png

Output Register

Registers_5 is a 4-bit Register with Positive-Edge Clock, Asynchronous Set and Clock Enable and can be used in an equivalent manner to a latch with the CE input port as the gate.


    outp_enable <= '1' when cpu_addr(15 downto 12) = "0101" and ram_wr_en = '1' else '0';
    outp_gate_0 <= (outp_enable and not cpu_addr(0));
    outp_gate_1 <= (outp_enable and cpu_addr(0));

    u_outp0 : entity work.registers_5
    port map (
        C => clk_sys,
        CE => outp_gate_0, -- use as gate input
        PRE => reset,
        D => cpu_data_out(3 downto 0),
        Q => outp_dout_0
    );

    u_outp1 : entity work.registers_5
    port map (
        C => clk_sys,
        CE => outp_gate_1, -- use as gate input
        PRE => reset,
        D => cpu_data_out(3 downto 0),
        Q => outp_dout_1
    );

    ext_outp <= outp_dout_1 & outp_dout_0;