-- VHDL description of Motorola MC14500B Industrial Control Unit -- Copyright 2002, 2006 Eric Smith -- $Id: mc14500b.vhdl,v 1.2 2006/10/29 03:04:47 eric Exp eric $ -- In the real MC14500B, there is an internal oscillator, which is stopped -- when rst is asserted. This model requires an externally supplied clock, -- and treats rst as a synchronous input. -- In the real MC14500B, the data pin is bidirectional. In this model, for -- ease of use in an FPGA, there are separate data_in and data_out signals. -- These may be tied together externally to the model. library ieee; use ieee.std_logic_1164.all; entity mc14500b is port (clk: in std_logic; rst: in std_logic; i: in std_logic_vector (3 downto 0); data_in: in std_logic; data_out: out std_logic; write: out std_logic; jmp: out std_logic; rtn: out std_logic; flg0: out std_logic; flgf: out std_logic ); end mc14500b; architecture behavioral of mc14500b is signal masked_data: std_logic; -- The MC14500B has an instruction register clocked on the falling -- edge of the clock input. signal ir: std_logic_vector (3 downto 0); -- The MC14500B has four internal state flip-flops, clocked on the -- rising edge of the clock input. signal ien: std_logic; signal oen: std_logic; signal skip: std_logic; signal rr: std_logic; begin masked_data <= data_in and ien; flg0 <= '1' when ir = "0000" else '0'; rtn <= '1' when ir = "1101" else '0'; jmp <= '1' when ir = "1100" else '0'; flgf <= '1' when ir = "1111" else '0'; write <= '1' when skip = '0' and oen = '1' and (ir = "1000" or ir = "1001") else '0'; -- It is not clear from the manual whether the MC14500B drives the data pin -- when there is a write instruction but OEN is zero. I'm assuming that it -- does not, in order to avoid contention from the input selector. data_out <= rr when skip = '0' and oen = '1' and ir = "1000" else not rr when skip = '0' and oen = '1' and ir = "1001" else 'Z'; process (clk) is begin if falling_edge (clk) then ir <= i; end if; end process; process (clk) is begin if rising_edge (clk) then if rst = '1' then ien <= '0'; elsif ir = "1010" and skip = '0' then ien <= data_in; end if; if rst = '1' then oen <= '0'; elsif ir = "1011" and skip = '0' then oen <= data_in; end if; if rst = '1' then skip <= '0'; elsif skip = '1' then skip <= '0'; elsif ir = "1101" then skip <= '1'; elsif ir = "1110" and rr = '0' then skip <= '1'; else skip <= '0'; end if; if rst = '1' then rr <= '0'; elsif ir = "0001" and skip = '0' then rr <= masked_data; elsif ir = "0010" and skip = '0' then rr <= not masked_data; elsif ir = "0011" and skip = '0' then rr <= rr and masked_data; elsif ir = "0100" and skip = '0' then rr <= rr and not masked_data; elsif ir = "0101" and skip = '0' then rr <= rr or masked_data; elsif ir = "0110" and skip = '0' then rr <= rr or not masked_data; elsif ir = "0111" and skip = '0' then rr <= rr xor not masked_data; end if; end if; end process; end behavioral;