summaryrefslogtreecommitdiffstats
path: root/hdl/PIC.vhd
diff options
context:
space:
mode:
Diffstat (limited to 'hdl/PIC.vhd')
-rw-r--r--hdl/PIC.vhd181
1 files changed, 181 insertions, 0 deletions
diff --git a/hdl/PIC.vhd b/hdl/PIC.vhd
new file mode 100644
index 0000000..a31bec7
--- /dev/null
+++ b/hdl/PIC.vhd
@@ -0,0 +1,181 @@
+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');
+ instruction_return : out std_logic := '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
+ );
+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(2 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 sm_data : std_logic_vector(7 downto 0);
+ signal sm_pc : std_logic_vector(12 downto 0);
+ signal we_w : std_logic;
+ signal instr_ret : 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;
+
+begin
+
+ work_reg <= W;
+ program_counter <= sm_pc;
+ instruction_return <= instr_ret;
+ status <= alu_status;
+
+ 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,
+ instr_ret => instr_ret,
+ 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
+ );
+
+ alu : entity work.alu(rtl)
+ port map (
+ a => W,
+ b => b_operand,
+ op => alu_operation,
+ bit_select => bit_select,
+ status_in => mem_qstatus,
+ 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 => 128)
+ port map (
+ clk => clk,
+ we => mem_we,
+ re => mem_re,
+ d => alu_result,
+ d_status => "00000" & alu_status,
+ addr => 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
+ );
+
+ 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;