library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.alu_types.all; entity PIC is generic ( CLK_FREQ : positive := 50_000_000; -- 50M, GW5A clock BAUD_RATE : positive := 115_200 ); port ( clk : in std_logic; reset : in std_logic; opcode : in std_logic_vector(13 downto 0); program_counter : out std_logic_vector(12 downto 0) := (others => '0'); work_reg : out std_logic_vector(7 downto 0) := (others => '0'); status : out std_logic_vector(2 downto 0) := (others => '0'); port_a : out std_logic_vector(7 downto 0) := (others => '0'); port_b : out std_logic_vector(7 downto 0) := (others => '0'); -- UART physical pins uart_tx : out std_logic; uart_rx : in std_logic; -- 1-Wire physical pin ow_pin : inout std_logic ); end entity PIC; architecture rtl of PIC is signal W : std_logic_vector(7 downto 0) := (others => '0'); signal alu_operation : alu_op; signal alu_result : std_logic_vector(7 downto 0); signal alu_skip : std_logic; signal mem_q : std_logic_vector(7 downto 0); signal mem_qstatus : std_logic_vector(7 downto 0); signal mem_we : std_logic; signal mem_re : std_logic; signal bit_select : std_logic_vector(2 downto 0); signal addr : std_logic_vector(6 downto 0); signal mem_addr : std_logic_vector(7 downto 0); signal sm_data : std_logic_vector(7 downto 0); signal sm_pc : std_logic_vector(12 downto 0); signal we_w : std_logic; signal alu_status : std_logic_vector(2 downto 0); signal use_literal : std_logic; signal we_status : std_logic; signal b_operand : std_logic_vector(7 downto 0); signal stack_push : std_logic; signal stack_pop : std_logic; signal stack_din : std_logic_vector(12 downto 0); signal stack_dout : std_logic_vector(12 downto 0); -- UART <-> dpram bridge signals signal uart_tx_byte : std_logic_vector(7 downto 0); signal uart_tx_send : std_logic; signal uart_tx_done : std_logic; signal uart_rx_byte : std_logic_vector(7 downto 0); signal uart_rx_rd_en : std_logic; signal uart_rx_empty : std_logic; signal uart_rx_full : std_logic; -- 1-Wire <-> dpram bridge signals signal ow_tx_byte : std_logic_vector(7 downto 0); signal ow_op : std_logic_vector(1 downto 0); signal ow_start : std_logic; signal ow_rx_byte : std_logic_vector(7 downto 0); signal ow_presence : std_logic; signal ow_busy : std_logic; -- Interrupt bridge signals signal irq_pending : std_logic; signal gie_clear : std_logic; signal gie_set : std_logic; -- Timer0 bridge signals signal t0if : std_logic; signal tmr0_val : std_logic_vector(7 downto 0); signal tmr0_we_sig : std_logic; signal tmr0_in_sig : std_logic_vector(7 downto 0); signal option_reg : std_logic_vector(7 downto 0); begin work_reg <= W; program_counter <= sm_pc; status <= alu_status; -- banking: RP0 (STATUS bit 5) selects bank 0 or bank 1 mem_addr <= mem_qstatus(5) & addr; b_operand_select : process(use_literal, sm_data, mem_q) begin if use_literal = '1' then b_operand <= sm_data; else b_operand <= mem_q; end if; end process; w_reg : process(clk) begin if rising_edge(clk) then if we_w = '1' then W <= alu_result; end if; end if; end process w_reg; sm : entity work.state_machine(rtl) port map ( clk => clk, opcode => opcode, reset => reset, op => alu_operation, we_mem => mem_we, re_mem => mem_re, we_w => we_w, bit_select => bit_select, data => sm_data, pc => sm_pc, addr => addr, use_literal => use_literal, we_status => we_status, stack_push => stack_push, stack_pop => stack_pop, stack_din => stack_din, stack_dout => stack_dout, alu_skip => alu_skip, alu_result => alu_result, irq_pending => irq_pending, gie_clear => gie_clear, gie_set => gie_set ); alu : entity work.alu(rtl) port map ( a => W, b => b_operand, op => alu_operation, bit_select => bit_select, status_in => mem_qstatus(2 downto 0), result => alu_result, status => alu_status, skip => alu_skip ); stk : entity work.stack(rtl) port map ( clk => clk, reset => reset, push => stack_push, pop => stack_pop, din => stack_din, dout => stack_dout ); mem : entity work.dpram(rtl) generic map (DEPTH => 256) port map ( clk => clk, we => mem_we, re => mem_re, d => alu_result, d_status => "00000" & alu_status, addr => mem_addr, q => mem_q, q_status => mem_qstatus, port_a => port_a, port_b => port_b, we_status => we_status, uart_tx_byte => uart_tx_byte, uart_tx_send => uart_tx_send, uart_tx_done => uart_tx_done, uart_rx_byte => uart_rx_byte, uart_rx_rd_en => uart_rx_rd_en, uart_rx_empty => uart_rx_empty, uart_rx_full => uart_rx_full, ow_tx_byte => ow_tx_byte, ow_op => ow_op, ow_start => ow_start, ow_rx_byte => ow_rx_byte, ow_presence => ow_presence, ow_busy => ow_busy, tmr0_val => tmr0_val, tmr0_we => tmr0_we_sig, tmr0_in => tmr0_in_sig, option_reg => option_reg, t0if_set => t0if, gie_clear => gie_clear, gie_set => gie_set, irq_pending => irq_pending ); ow_inst : entity work.onewire generic map ( CLK_FREQ => CLK_FREQ ) port map ( clk => clk, reset => reset, ow_pin => ow_pin, start => ow_start, op => ow_op, tx_byte => ow_tx_byte, rx_byte => ow_rx_byte, presence => ow_presence, busy => ow_busy, done => open ); tmr0_inst : entity work.timer0(rtl) generic map ( CLK_FREQ => CLK_FREQ ) port map ( clk => clk, reset => reset, t0cki => '0', t0cs => option_reg(5), t0se => option_reg(4), psa => option_reg(3), ps => option_reg(2 downto 0), tmr0_we => tmr0_we_sig, tmr0_in => tmr0_in_sig, tmr0_out => tmr0_val, t0if => t0if ); uart_inst : entity work.uart generic map ( CLK_FREQ => CLK_FREQ, BAUD_RATE => BAUD_RATE, CLKS_PER_BIT => CLK_FREQ / BAUD_RATE ) port map ( clk => clk, tx_should_send => uart_tx_send, byte_in => uart_tx_byte, tx_done => uart_tx_done, baud_tick => open, uart_tx => uart_tx, uart_rx => uart_rx, rd_en => uart_rx_rd_en, rx_data => uart_rx_byte, rx_empty => uart_rx_empty, rx_full => uart_rx_full ); end architecture rtl;