diff --git a/Makefile b/Makefile index e486a29..2c836b5 100644 --- a/Makefile +++ b/Makefile @@ -63,7 +63,7 @@ soc_files = wishbone_arbiter.vhdl wishbone_bram_wrapper.vhdl sync_fifo.vhdl \ uart_files = $(wildcard uart16550/*.v) -soc_sim_files = $(core_files) $(soc_files) sim_console.vhdl sim_pp_uart.vhdl sim_bram_helpers.vhdl \ +soc_sim_files = $(core_files) $(soc_files) sim_console.vhdl sim_bram_helpers.vhdl \ sim_bram.vhdl sim_jtag_socket.vhdl sim_jtag.vhdl dmi_dtm_xilinx.vhdl \ sim_16550_uart.vhdl \ foreign_random.vhdl glibc_random.vhdl glibc_random_helpers.vhdl @@ -190,7 +190,7 @@ clkgen=fpga/clk_gen_bypass.vhd endif fpga_files = fpga/soc_reset.vhdl \ - fpga/pp_fifo.vhd fpga/pp_soc_uart.vhd fpga/main_bram.vhdl \ + fpga/main_bram.vhdl \ nonrandom.vhdl synth_files = $(core_files) $(soc_files) $(fpga_files) $(clkgen) $(toplevel) $(dmi_dtm) diff --git a/fpga/pp_fifo.vhd b/fpga/pp_fifo.vhd deleted file mode 100644 index 553a499..0000000 --- a/fpga/pp_fifo.vhd +++ /dev/null @@ -1,91 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2015 - -library ieee; -use ieee.std_logic_1164.all; - ---! @brief A generic FIFO module. ---! Adopted from the FIFO module in . -entity pp_fifo is - generic( - DEPTH : natural := 64; - WIDTH : natural := 32 - ); - port( - -- Control lines: - clk : in std_logic; - reset : in std_logic; - - -- Status lines: - full : out std_logic; - empty : out std_logic; - - -- Data in: - data_in : in std_logic_vector(WIDTH - 1 downto 0); - data_out : out std_logic_vector(WIDTH - 1 downto 0); - push, pop : in std_logic - ); -end entity pp_fifo; - -architecture behaviour of pp_fifo is - - type memory_array is array(0 to DEPTH - 1) of std_logic_vector(WIDTH - 1 downto 0); - signal memory : memory_array := (others => (others => '0')); - - subtype index_type is integer range 0 to DEPTH - 1; - signal top, bottom : index_type; - - type fifo_op is (FIFO_POP, FIFO_PUSH); - signal prev_op : fifo_op := FIFO_POP; - -begin - - empty <= '1' when top = bottom and prev_op = FIFO_POP else '0'; - full <= '1' when top = bottom and prev_op = FIFO_PUSH else '0'; - - read: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - bottom <= 0; - else - if pop = '1' then - data_out <= memory(bottom); - bottom <= (bottom + 1) mod DEPTH; - end if; - end if; - end if; - end process read; - - write: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - top <= 0; - else - if push = '1' then - memory(top) <= data_in; - top <= (top + 1) mod DEPTH; - end if; - end if; - end if; - end process write; - - set_prev_op: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - prev_op <= FIFO_POP; - else - if push = '1' and pop = '1' then - -- Keep the same value for prev_op - elsif push = '1' then - prev_op <= FIFO_PUSH; - elsif pop = '1' then - prev_op <= FIFO_POP; - end if; - end if; - end if; - end process set_prev_op; - -end architecture behaviour; diff --git a/fpga/pp_soc_uart.vhd b/fpga/pp_soc_uart.vhd deleted file mode 100644 index 1ed3bb9..0000000 --- a/fpga/pp_soc_uart.vhd +++ /dev/null @@ -1,395 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - 2016 - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - ---! @brief Simple UART module. ---! The following registers are defined: ---! |--------------------|--------------------------------------------| ---! | Address | Description | ---! |--------------------|--------------------------------------------| ---! | 0x00 | Transmit register (write-only) | ---! | 0x08 | Receive register (read-only) | ---! | 0x10 | Status register (read-only) | ---! | 0x18 | Sample clock divisor register (read/write) | ---! | 0x20 | Interrupt enable register (read/write) | ---! |--------------------|--------------------------------------------| ---! ---! The status register contains the following bits: ---! - Bit 0: receive buffer empty ---! - Bit 1: transmit buffer empty ---! - Bit 2: receive buffer full ---! - Bit 3: transmit buffer full ---! ---! The sample clock divisor should be set according to the formula: ---! sample_clk = (f_clk / (baudrate * 16)) - 1 ---! ---! If the sample clock divisor register is set to 0, the sample clock ---! is stopped. ---! ---! Interrupts are enabled by setting the corresponding bit in the interrupt ---! enable register. The following bits are available: ---! - Bit 0: data received (receive buffer not empty) ---! - Bit 1: ready to send data (transmit buffer empty) -entity pp_soc_uart is - generic( - FIFO_DEPTH : natural := 64 --! Depth of the input and output FIFOs. - ); - port( - clk : in std_logic; - reset : in std_logic; - - -- UART ports: - txd : out std_logic; - rxd : in std_logic; - - -- Interrupt signal: - irq : out std_logic; - - -- Wishbone ports: - wb_adr_in : in std_logic_vector(11 downto 0); - wb_dat_in : in std_logic_vector( 7 downto 0); - wb_dat_out : out std_logic_vector( 7 downto 0); - wb_we_in : in std_logic; - wb_cyc_in : in std_logic; - wb_stb_in : in std_logic; - wb_ack_out : out std_logic - ); -end entity pp_soc_uart; - -architecture behaviour of pp_soc_uart is - - subtype bitnumber is natural range 0 to 7; --! Type representing the index of a bit. - - -- UART sample clock signals: - signal sample_clk : std_logic; - signal sample_clk_divisor : std_logic_vector(7 downto 0); - signal sample_clk_counter : std_logic_vector(sample_clk_divisor'range); - - -- UART receive process signals: - type rx_state_type is (IDLE, RECEIVE, STARTBIT, STOPBIT); - signal rx_state : rx_state_type; - signal rx_byte : std_logic_vector(7 downto 0); - signal rx_current_bit : bitnumber; - - subtype rx_sample_counter_type is natural range 0 to 15; - signal rx_sample_counter : rx_sample_counter_type; - signal rx_sample_value : rx_sample_counter_type; - - subtype rx_sample_delay_type is natural range 0 to 7; - signal rx_sample_delay : rx_sample_delay_type; - - -- UART transmit process signals: - type tx_state_type is (IDLE, TRANSMIT, STOPBIT); - signal tx_state : tx_state_type; - signal tx_byte : std_logic_vector(7 downto 0); - signal tx_current_bit : bitnumber; - - -- UART transmit clock: - subtype uart_tx_counter_type is natural range 0 to 15; - signal uart_tx_counter : uart_tx_counter_type := 0; - signal uart_tx_clk : std_logic; - - -- Buffer signals: - signal send_buffer_full, send_buffer_empty : std_logic; - signal recv_buffer_full, recv_buffer_empty : std_logic; - signal send_buffer_input, send_buffer_output : std_logic_vector(7 downto 0); - signal recv_buffer_input, recv_buffer_output : std_logic_vector(7 downto 0); - signal send_buffer_push, send_buffer_pop : std_logic := '0'; - signal recv_buffer_push, recv_buffer_pop : std_logic := '0'; - - -- IRQ enable signals: - signal irq_recv_enable, irq_tx_ready_enable : std_logic := '0'; - - -- Wishbone signals: - type wb_state_type is (IDLE, WRITE_ACK, READ_ACK); - signal wb_state : wb_state_type; - - signal rxd2 : std_logic := '1'; - signal rxd3 : std_logic := '1'; - signal txd2 : std_ulogic := '1'; -begin - - irq <= (irq_recv_enable and (not recv_buffer_empty)) - or (irq_tx_ready_enable and send_buffer_empty); - - ---------- UART receive ---------- - - recv_buffer_input <= rx_byte; - - -- Add a few FFs on the RX input to avoid metastability issues - process (clk) is - begin - if rising_edge(clk) then - rxd3 <= rxd2; - rxd2 <= rxd; - end if; - end process; - txd <= txd2; - - uart_receive: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - rx_state <= IDLE; - recv_buffer_push <= '0'; - else - case rx_state is - when IDLE => - if recv_buffer_push = '1' then - recv_buffer_push <= '0'; - end if; - - if sample_clk = '1' and rxd3 = '0' then - rx_sample_value <= rx_sample_counter; - rx_sample_delay <= 0; - rx_current_bit <= 0; - rx_state <= STARTBIT; - end if; - when STARTBIT => - if sample_clk = '1' then - if rx_sample_delay = 7 then - rx_state <= RECEIVE; - rx_sample_value <= rx_sample_counter; - rx_sample_delay <= 0; - else - rx_sample_delay <= rx_sample_delay + 1; - end if; - end if; - when RECEIVE => - if sample_clk = '1' and rx_sample_counter = rx_sample_value then - if rx_current_bit /= 7 then - rx_byte(rx_current_bit) <= rxd3; - rx_current_bit <= rx_current_bit + 1; - else - rx_byte(rx_current_bit) <= rxd3; - rx_state <= STOPBIT; - end if; - end if; - when STOPBIT => - if sample_clk = '1' and rx_sample_counter = rx_sample_value then - rx_state <= IDLE; - - if recv_buffer_full = '0' then - recv_buffer_push <= '1'; - end if; - end if; - end case; - end if; - end if; - end process uart_receive; - - sample_counter: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - rx_sample_counter <= 0; - elsif sample_clk = '1' then - if rx_sample_counter = 15 then - rx_sample_counter <= 0; - else - rx_sample_counter <= rx_sample_counter + 1; - end if; - end if; - end if; - end process sample_counter; - - ---------- UART transmit ---------- - - tx_byte <= send_buffer_output; - - uart_transmit: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - txd2 <= '1'; - tx_state <= IDLE; - send_buffer_pop <= '0'; - tx_current_bit <= 0; - else - case tx_state is - when IDLE => - if send_buffer_empty = '0' and uart_tx_clk = '1' then - txd2 <= '0'; - send_buffer_pop <= '1'; - tx_current_bit <= 0; - tx_state <= TRANSMIT; - elsif uart_tx_clk = '1' then - txd2 <= '1'; - end if; - when TRANSMIT => - if send_buffer_pop = '1' then - send_buffer_pop <= '0'; - elsif uart_tx_clk = '1' and tx_current_bit = 7 then - txd2 <= tx_byte(tx_current_bit); - tx_state <= STOPBIT; - elsif uart_tx_clk = '1' then - txd2 <= tx_byte(tx_current_bit); - tx_current_bit <= tx_current_bit + 1; - end if; - when STOPBIT => - if uart_tx_clk = '1' then - txd2 <= '1'; - tx_state <= IDLE; - end if; - end case; - end if; - end if; - end process uart_transmit; - - uart_tx_clock_generator: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - uart_tx_counter <= 0; - uart_tx_clk <= '0'; - else - if sample_clk = '1' then - if uart_tx_counter = 15 then - uart_tx_counter <= 0; - uart_tx_clk <= '1'; - else - uart_tx_counter <= uart_tx_counter + 1; - uart_tx_clk <= '0'; - end if; - else - uart_tx_clk <= '0'; - end if; - end if; - end if; - end process uart_tx_clock_generator; - - ---------- Sample clock generator ---------- - - sample_clock_generator: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - sample_clk_counter <= (others => '0'); - sample_clk <= '0'; - else - if sample_clk_divisor /= x"00" then - if sample_clk_counter = sample_clk_divisor then - sample_clk_counter <= (others => '0'); - sample_clk <= '1'; - else - sample_clk_counter <= std_logic_vector(unsigned(sample_clk_counter) + 1); - sample_clk <= '0'; - end if; - end if; - end if; - end if; - end process sample_clock_generator; - - ---------- Data Buffers ---------- - - send_buffer: entity work.pp_fifo - generic map( - DEPTH => FIFO_DEPTH, - WIDTH => 8 - ) port map( - clk => clk, - reset => reset, - full => send_buffer_full, - empty => send_buffer_empty, - data_in => send_buffer_input, - data_out => send_buffer_output, - push => send_buffer_push, - pop => send_buffer_pop - ); - - recv_buffer: entity work.pp_fifo - generic map( - DEPTH => FIFO_DEPTH, - WIDTH => 8 - ) port map( - clk => clk, - reset => reset, - full => recv_buffer_full, - empty => recv_buffer_empty, - data_in => recv_buffer_input, - data_out => recv_buffer_output, - push => recv_buffer_push, - pop => recv_buffer_pop - ); - - ---------- Wishbone Interface ---------- - - wishbone: process(clk) - begin - if rising_edge(clk) then - if reset = '1' then - wb_ack_out <= '0'; - wb_state <= IDLE; - send_buffer_push <= '0'; - recv_buffer_pop <= '0'; - sample_clk_divisor <= (others => '0'); - irq_recv_enable <= '0'; - irq_tx_ready_enable <= '0'; - else - case wb_state is - when IDLE => - if wb_cyc_in = '1' and wb_stb_in = '1' then - if wb_we_in = '1' then -- Write to register - if wb_adr_in = x"000" then - send_buffer_input <= wb_dat_in; - send_buffer_push <= '1'; - elsif wb_adr_in = x"018" then - sample_clk_divisor <= wb_dat_in; - elsif wb_adr_in = x"020" then - irq_recv_enable <= wb_dat_in(0); - irq_tx_ready_enable <= wb_dat_in(1); - end if; - - -- Invalid writes are acked and ignored. - wb_ack_out <= '1'; - wb_state <= WRITE_ACK; - else -- Read from register - if wb_adr_in = x"008" then - recv_buffer_pop <= '1'; - elsif wb_adr_in = x"010" then - wb_dat_out <= x"0" & send_buffer_full & recv_buffer_full & - send_buffer_empty & recv_buffer_empty; - wb_ack_out <= '1'; - elsif wb_adr_in = x"018" then - wb_dat_out <= sample_clk_divisor; - wb_ack_out <= '1'; - elsif wb_adr_in = x"020" then - wb_dat_out <= (0 => irq_recv_enable, - 1 => irq_tx_ready_enable, - others => '0'); - wb_ack_out <= '1'; - else - wb_dat_out <= (others => '0'); - wb_ack_out <= '1'; - end if; - wb_state <= READ_ACK; - end if; - end if; - when WRITE_ACK => - send_buffer_push <= '0'; - - if wb_stb_in = '0' then - wb_ack_out <= '0'; - wb_state <= IDLE; - end if; - when READ_ACK => - if recv_buffer_pop = '1' then - recv_buffer_pop <= '0'; - else - wb_dat_out <= recv_buffer_output; - wb_ack_out <= '1'; - end if; - - if wb_stb_in = '0' then - wb_ack_out <= '0'; - wb_state <= IDLE; - end if; - end case; - end if; - end if; - end process wishbone; - -end architecture behaviour; diff --git a/fpga/pp_utilities.vhd b/fpga/pp_utilities.vhd deleted file mode 100644 index 959b7a4..0000000 --- a/fpga/pp_utilities.vhd +++ /dev/null @@ -1,90 +0,0 @@ --- The Potato Processor - A simple processor for FPGAs --- (c) Kristian Klomsten Skordal 2014 - -library ieee; -use ieee.std_logic_1164.all; - -package pp_utilities is - - --! Converts a boolean to an std_logic. - function to_std_logic(input : in boolean) return std_logic; - - -- Checks if a number is 2^n: - function is_pow2(input : in natural) return boolean; - - --! Calculates log2 with integers. - function log2(input : in natural) return natural; - - -- Gets the value of the sel signals to the wishbone interconnect for the specified - -- operand size and address. - function wb_get_data_sel(size : in std_logic_vector(1 downto 0); address : in std_logic_vector) - return std_logic_vector; - -end package pp_utilities; - -package body pp_utilities is - - function to_std_logic(input : in boolean) return std_logic is - begin - if input then - return '1'; - else - return '0'; - end if; - end function to_std_logic; - - function is_pow2(input : in natural) return boolean is - variable c : natural := 1; - begin - for i in 0 to 31 loop - if input = c then - return true; - end if; - - c := c * 2; - end loop; - - return false; - end function is_pow2; - - function log2(input : in natural) return natural is - variable retval : natural := 0; - variable temp : natural := input; - begin - while temp > 1 loop - retval := retval + 1; - temp := temp / 2; - end loop; - - return retval; - end function log2; - - function wb_get_data_sel(size : in std_logic_vector(1 downto 0); address : in std_logic_vector) - return std_logic_vector is - begin - case size is - when b"01" => - case address(1 downto 0) is - when b"00" => - return b"0001"; - when b"01" => - return b"0010"; - when b"10" => - return b"0100"; - when b"11" => - return b"1000"; - when others => - return b"0001"; - end case; - when b"10" => - if address(1) = '0' then - return b"0011"; - else - return b"1100"; - end if; - when others => - return b"1111"; - end case; - end function wb_get_data_sel; - -end package body pp_utilities; diff --git a/fpga/top-acorn-cle-215.vhdl b/fpga/top-acorn-cle-215.vhdl index bcbadad..4c3609b 100644 --- a/fpga/top-acorn-cle-215.vhdl +++ b/fpga/top-acorn-cle-215.vhdl @@ -19,8 +19,7 @@ entity toplevel is SPI_FLASH_OFFSET : integer := 10485760; SPI_FLASH_DEF_CKDV : natural := 1; SPI_FLASH_DEF_QUAD : boolean := true; - LOG_LENGTH : natural := 2048; - UART_IS_16550 : boolean := true + LOG_LENGTH : natural := 2048 ); port( clk200_p : in std_ulogic; @@ -133,8 +132,7 @@ begin SPI_FLASH_OFFSET => SPI_FLASH_OFFSET, SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV, SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD, - LOG_LENGTH => LOG_LENGTH, - UART0_IS_16550 => UART_IS_16550 + LOG_LENGTH => LOG_LENGTH ) port map ( -- System signals diff --git a/fpga/top-arty.vhdl b/fpga/top-arty.vhdl index 8e6ff02..7aeb308 100644 --- a/fpga/top-arty.vhdl +++ b/fpga/top-arty.vhdl @@ -25,7 +25,6 @@ entity toplevel is SPI_FLASH_DEF_QUAD : boolean := true; LOG_LENGTH : natural := 512; USE_LITEETH : boolean := false; - UART_IS_16550 : boolean := false; HAS_UART1 : boolean := true; USE_LITESDCARD : boolean := false; NGPIO : natural := 32 @@ -204,7 +203,6 @@ begin SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD, LOG_LENGTH => LOG_LENGTH, HAS_LITEETH => USE_LITEETH, - UART0_IS_16550 => UART_IS_16550, HAS_UART1 => HAS_UART1, HAS_SD_CARD => USE_LITESDCARD, NGPIO => NGPIO diff --git a/fpga/top-generic.vhdl b/fpga/top-generic.vhdl index c75e465..d522fb1 100644 --- a/fpga/top-generic.vhdl +++ b/fpga/top-generic.vhdl @@ -15,8 +15,7 @@ entity toplevel is HAS_BTC : boolean := false; ICACHE_NUM_LINES : natural := 64; LOG_LENGTH : natural := 512; - DISABLE_FLATTEN_CORE : boolean := false; - UART_IS_16550 : boolean := true + DISABLE_FLATTEN_CORE : boolean := false ); port( ext_clk : in std_ulogic; @@ -76,8 +75,7 @@ begin HAS_BTC => HAS_BTC, ICACHE_NUM_LINES => ICACHE_NUM_LINES, LOG_LENGTH => LOG_LENGTH, - DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE, - UART0_IS_16550 => UART_IS_16550 + DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE ) port map ( system_clk => system_clk, diff --git a/fpga/top-genesys2.vhdl b/fpga/top-genesys2.vhdl index fcd190f..642b6d4 100644 --- a/fpga/top-genesys2.vhdl +++ b/fpga/top-genesys2.vhdl @@ -20,8 +20,7 @@ entity toplevel is SPI_FLASH_OFFSET : integer := 10485760; SPI_FLASH_DEF_CKDV : natural := 1; SPI_FLASH_DEF_QUAD : boolean := true; - LOG_LENGTH : natural := 2048; - UART_IS_16550 : boolean := true + LOG_LENGTH : natural := 2048 ); port( clk200_p : in std_ulogic; @@ -136,8 +135,7 @@ begin SPI_FLASH_OFFSET => SPI_FLASH_OFFSET, SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV, SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD, - LOG_LENGTH => LOG_LENGTH, - UART0_IS_16550 => UART_IS_16550 + LOG_LENGTH => LOG_LENGTH ) port map ( -- System signals diff --git a/fpga/top-nexys-video.vhdl b/fpga/top-nexys-video.vhdl index 1cf1df2..0d0a242 100644 --- a/fpga/top-nexys-video.vhdl +++ b/fpga/top-nexys-video.vhdl @@ -23,7 +23,6 @@ entity toplevel is SPI_FLASH_DEF_CKDV : natural := 1; SPI_FLASH_DEF_QUAD : boolean := true; LOG_LENGTH : natural := 2048; - UART_IS_16550 : boolean := true; USE_LITEETH : boolean := false; USE_LITESDCARD : boolean := false ); @@ -180,7 +179,6 @@ begin SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV, SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD, LOG_LENGTH => LOG_LENGTH, - UART0_IS_16550 => UART_IS_16550, HAS_LITEETH => USE_LITEETH, HAS_SD_CARD => USE_LITESDCARD ) diff --git a/hello_world/hello_world.bin b/hello_world/hello_world.bin index e4b14ca..7f49a41 100755 Binary files a/hello_world/hello_world.bin and b/hello_world/hello_world.bin differ diff --git a/hello_world/hello_world.elf b/hello_world/hello_world.elf index 5eeedc4..c617d84 100755 Binary files a/hello_world/hello_world.elf and b/hello_world/hello_world.elf differ diff --git a/hello_world/hello_world.hex b/hello_world/hello_world.hex index 763797e..3ed733b 100644 --- a/hello_world/hello_world.hex +++ b/hello_world/hello_world.hex @@ -515,48 +515,33 @@ e8010010ebc1fff0 3c4000014e800020 7c0802a638429800 f8010010fbe1fff8 -480001edf821ffd1 +48000175f821ffd1 6000000060000000 -4800015538628000 +480000dd38628000 4800004960000000 7c7f1b7860000000 57ff063e5463063e -60000000480000b9 +600000004800007d 4082ffe02c1f000d -480000a53860000a +480000693860000a 4bffffd060000000 0100000000000000 3c40000100000180 6000000038429800 -6000000089228090 -2c09000039428088 -e92a000041820030 -7c0004ac39290014 -712900017d204eaa -e86a00004182ffec +39290014e9228088 +7d204eaa7c0004ac +4182ffe871290001 +e862808860000000 7c601eaa7c0004ac 4e8000205463063e -39290010e92a0000 -7d204eea7c0004ac -4082ffec71290001 -38630008e86a0000 -7c601eea7c0004ac -000000004bffffd0 0000000000000000 -384298003c400001 -8922809060000000 -3942808860000000 -4182002c2c090000 -39290014e92a0000 +3c40000100000000 +6000000038429800 +39290014e9228088 7d204eaa7c0004ac -4182ffec71290020 -7c0004ace92a0000 -4e8000207c604faa -39290010e92a0000 -7d204eea7c0004ac -4082ffec71290008 -e94a00005469063e -7d2057ea7c0004ac +4182ffe871290020 +e922808860000000 +7c604faa7c0004ac 000000004e800020 0000000000000000 384298003c400001 @@ -565,10 +550,10 @@ fbe1fff87c0802a6 f821ffd1f8010010 2c3e00008fdf0001 3821003040820010 -4bfffe4438600000 +4bfffebc38600000 4082000c281e000a -4bffff453860000d -4bffff3d7fc3f378 +4bffff813860000d +4bffff797fc3f378 000000004bffffd0 0000028001000000 386000007c691b78 @@ -577,29 +562,26 @@ f821ffd1f8010010 000000004bfffff0 0000000000000000 384298003c400001 -614a00203d40c000 -7c0004ac794a0020 -3d20c0007d4056ea -61290008794a0600 +612900203d20c000 7c0004ac79290020 -712900207d204eea -3d20c00041820018 -7929002061290040 -7d204eea7c0004ac -3d00c0007929f804 -6108200079290fc3 -6000000079080020 -3d00001cf9028088 -7d4a439261082000 -6000000041820084 -9922809039200001 -6108200c3d00c000 -790800203920ff80 -7d2047aa7c0004ac -7c0004ace9228088 -e92280887d404faa -39290004794ac202 -7d404faa7c0004ac +3d40c0007d204eea +614a000879290600 +7c0004ac794a0020 +714a00207d4056ea +3d40c00041820018 +794a0020614a0040 +7d4056ea7c0004ac +600000003d40c000 +3d00c000614a2000 +6108200c794a0020 +f942808879080020 +614a20003d40001c +3940ff807d295392 +7d4047aa7c0004ac +7c0004ace9428088 +e94280887d2057aa +394a00047929c202 +7d2057aa7c0004ac 39400003e9228088 7c0004ac3929000c e92280887d404faa @@ -607,53 +589,71 @@ e92280887d404faa e92280887d404faa 3929000839400007 7d404faa7c0004ac -600000004e800020 -99228090394affff -612920183d20c000 -7c0004ac79290020 -4e8000207d404fea +000000004e800020 0000000000000000 -3c40000100000000 -6000000038429800 -2c24000089228090 -600000002f890000 -419e0030e9228088 -3940000241820024 +384298003c400001 +392000002c240000 +3920000241820008 418200082c230000 -39290004614a0001 -7d404faa7c0004ac -394000004e800020 -418200084bffffe0 -3929002060630002 -7c604fea7c0004ac +6000000061290001 +394a0004e9428088 +7d2057aa7c0004ac 000000004e800020 0000000000000000 0000000000000010 0141780400527a01 0000001800010c1b -fffffc4800000018 +fffffd2800000018 300e460000000070 000000019f7e4111 0000000000000010 0141780400527a01 0000001000010c1b -fffffc8800000018 -0000000000000084 +fffffd6800000018 +0000000000000048 0000002c00000010 -00000080fffffcf8 +00000044fffffd9c 0000002800000000 -fffffd6400000040 +fffffdcc00000040 4109450000000060 300e43029e019f00 42000e0a447e4111 0000000b4106dedf 0000006c00000010 -00000028fffffd98 +00000028fffffe00 0000001000000000 -fffffdac00000080 -000000000000012c +fffffe1400000080 +00000000000000f0 0000009400000010 -00000074fffffec4 +00000048fffffef0 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 0000000000000000 0000000000000000 0000000000000000 diff --git a/include/microwatt_soc.h b/include/microwatt_soc.h index b138be1..0d87009 100644 --- a/include/microwatt_soc.h +++ b/include/microwatt_soc.h @@ -60,21 +60,6 @@ #define SYS_REG_UART_IS_16550 (1ull << 32) -/* - * Register definitions for the potato UART - */ -#define POTATO_CONSOLE_TX 0x00 -#define POTATO_CONSOLE_RX 0x08 -#define POTATO_CONSOLE_STATUS 0x10 -#define POTATO_CONSOLE_STATUS_RX_EMPTY 0x01 -#define POTATO_CONSOLE_STATUS_TX_EMPTY 0x02 -#define POTATO_CONSOLE_STATUS_RX_FULL 0x04 -#define POTATO_CONSOLE_STATUS_TX_FULL 0x08 -#define POTATO_CONSOLE_CLOCK_DIV 0x18 -#define POTATO_CONSOLE_IRQ_EN 0x20 -#define POTATO_CONSOLE_IRQ_RX 0x01 -#define POTATO_CONSOLE_IRQ_TX 0x02 - /* * Register definitionss for our standard (16550 style) UART */ diff --git a/lib/console.c b/lib/console.c index 0750190..cfdebff 100644 --- a/lib/console.c +++ b/lib/console.c @@ -11,8 +11,6 @@ * Core UART functions to implement for a port */ -bool uart_is_std; - static uint64_t uart_base; static unsigned long uart_divisor(unsigned long uart_freq, unsigned long bauds) @@ -20,75 +18,6 @@ static unsigned long uart_divisor(unsigned long uart_freq, unsigned long bauds) return uart_freq / (bauds * 16); } -static uint64_t potato_uart_reg_read(int offset) -{ - return readq(uart_base + offset); -} - -static void potato_uart_reg_write(int offset, uint64_t val) -{ - writeq(val, uart_base + offset); -} - -static int potato_uart_rx_empty(void) -{ - uint64_t val; - - val = potato_uart_reg_read(POTATO_CONSOLE_STATUS); - - if (val & POTATO_CONSOLE_STATUS_RX_EMPTY) - return 1; - - return 0; -} - -static int potato_uart_tx_full(void) -{ - uint64_t val; - - val = potato_uart_reg_read(POTATO_CONSOLE_STATUS); - - if (val & POTATO_CONSOLE_STATUS_TX_FULL) - return 1; - - return 0; -} - -static char potato_uart_read(void) -{ - uint64_t val; - - val = potato_uart_reg_read(POTATO_CONSOLE_RX); - - return (char)(val & 0x000000ff); -} - -static void potato_uart_write(char c) -{ - uint64_t val; - - val = c; - - potato_uart_reg_write(POTATO_CONSOLE_TX, val); -} - -static void potato_uart_init(uint64_t uart_freq) -{ - unsigned long div = uart_divisor(uart_freq, UART_BAUDS) - 1; - potato_uart_reg_write(POTATO_CONSOLE_CLOCK_DIV, div); -} - -static void potato_uart_set_irq_en(bool rx_irq, bool tx_irq) -{ - uint64_t en = 0; - - if (rx_irq) - en |= POTATO_CONSOLE_IRQ_RX; - if (tx_irq) - en |= POTATO_CONSOLE_IRQ_TX; - potato_uart_reg_write(POTATO_CONSOLE_IRQ_EN, en); -} - static bool std_uart_rx_empty(void) { return !(readb(uart_base + UART_REG_LSR) & UART_REG_LSR_DR); @@ -137,28 +66,16 @@ static void std_uart_init(uint64_t uart_freq) int getchar(void) { - if (uart_is_std) { - while (std_uart_rx_empty()) - /* Do nothing */ ; - return std_uart_read(); - } else { - while (potato_uart_rx_empty()) - /* Do nothing */ ; - return potato_uart_read(); - } + while (std_uart_rx_empty()) + /* Do nothing */ ; + return std_uart_read(); } int putchar(int c) { - if (uart_is_std) { - while(std_uart_tx_full()) - /* Do Nothing */; - std_uart_write(c); - } else { - while (potato_uart_tx_full()) - /* Do Nothing */; - potato_uart_write(c); - } + while(std_uart_tx_full()) + /* Do Nothing */; + std_uart_write(c); return c; } @@ -205,19 +122,10 @@ void console_init(void) uart_freq = proc_freq; uart_base = UART_BASE; - if (uart_info & SYS_REG_UART_IS_16550) { - uart_is_std = true; - std_uart_init(proc_freq); - } else { - uart_is_std = false; - potato_uart_init(proc_freq); - } + std_uart_init(proc_freq); } void console_set_irq_en(bool rx_irq, bool tx_irq) { - if (uart_is_std) - std_uart_set_irq_en(rx_irq, tx_irq); - else - potato_uart_set_irq_en(rx_irq, tx_irq); + std_uart_set_irq_en(rx_irq, tx_irq); } diff --git a/microwatt.core b/microwatt.core index b01983f..e55dca1 100644 --- a/microwatt.core +++ b/microwatt.core @@ -55,9 +55,6 @@ filesets: files: - fpga/main_bram.vhdl - fpga/soc_reset.vhdl - - fpga/pp_fifo.vhd - - fpga/pp_soc_uart.vhd - - fpga/pp_utilities.vhd - fpga/firmware.hex : {copyto : firmware.hex, file_type : user} file_type : vhdlSource-2008 @@ -134,7 +131,6 @@ targets: - clk_frequency - disable_flatten_core - log_length=2048 - - uart_is_16550 - has_fpu - has_btc tools: @@ -152,7 +148,6 @@ targets: - disable_flatten_core - spi_flash_offset=10485760 - log_length=2048 - - uart_is_16550 tools: vivado: {part : xc7a200tsbg484-2} toplevel : toplevel @@ -169,7 +164,6 @@ targets: - disable_flatten_core - spi_flash_offset=10485760 - log_length=2048 - - uart_is_16550=false tools: vivado: {part : xc7k325tffg900-2} toplevel : toplevel @@ -185,7 +179,6 @@ targets: - no_bram - spi_flash_offset=10485760 - log_length=2048 - - uart_is_16550 generate: [litedram_acorn_cle_215] tools: vivado: {part : xc7a200tsbg484-2} @@ -202,7 +195,6 @@ targets: - no_bram - spi_flash_offset=10485760 - log_length=2048 - - uart_is_16550=false generate: [litedram_genesys2] tools: vivado: {part : xc7k325tffg900-2} @@ -219,7 +211,6 @@ targets: - disable_flatten_core - spi_flash_offset=10485760 - log_length=2048 - - uart_is_16550 - has_fpu - has_btc tools: @@ -239,7 +230,6 @@ targets: - no_bram - spi_flash_offset=10485760 - log_length=2048 - - uart_is_16550 - has_fpu - has_btc generate: [litedram_nexys_video, liteeth_nexys_video, litesdcard_nexys_video] @@ -258,7 +248,6 @@ targets: - disable_flatten_core - spi_flash_offset=3145728 - log_length=512 - - uart_is_16550 - has_uart1 - has_fpu=false - has_btc=false @@ -280,7 +269,6 @@ targets: - no_bram - spi_flash_offset=3145728 - log_length=512 - - uart_is_16550 - has_uart1 - has_fpu=false - has_btc=false @@ -300,7 +288,6 @@ targets: - disable_flatten_core - spi_flash_offset=4194304 - log_length=2048 - - uart_is_16550 - has_uart1 - has_fpu - has_btc @@ -322,7 +309,6 @@ targets: - no_bram - spi_flash_offset=4194304 - log_length=2048 - - uart_is_16550 - has_uart1 - has_fpu - has_btc @@ -342,7 +328,6 @@ targets: - clk_frequency - disable_flatten_core - log_length=512 - - uart_is_16550 - has_fpu=false - has_btc=false tools: @@ -453,12 +438,6 @@ parameters: paramtype : generic default : false - uart_is_16550: - datatype : bool - description : Use 16550-compatible UART from OpenCores - paramtype : generic - default : true - has_uart1: datatype : bool description : Enable second UART (always 16550-compatible) diff --git a/sim_pp_uart.vhdl b/sim_pp_uart.vhdl deleted file mode 100644 index 6641da5..0000000 --- a/sim_pp_uart.vhdl +++ /dev/null @@ -1,135 +0,0 @@ --- Sim console UART, provides the same interface as potato UART by --- Kristian Klomsten Skordal. - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library work; -use work.wishbone_types.all; -use work.sim_console.all; - ---! @brief Simple UART module. ---! The following registers are defined: ---! |--------------------|--------------------------------------------| ---! | Address | Description | ---! |--------------------|--------------------------------------------| ---! | 0x00 | Transmit register (write-only) | ---! | 0x08 | Receive register (read-only) | ---! | 0x10 | Status register (read-only) | ---! | 0x18 | Sample clock divisor register (dummy) | ---! | 0x20 | Interrupt enable register (read/write) | ---! |--------------------|--------------------------------------------| ---! ---! The status register contains the following bits: ---! - Bit 0: receive buffer empty ---! - Bit 1: transmit buffer empty ---! - Bit 2: receive buffer full ---! - Bit 3: transmit buffer full ---! ---! Interrupts are enabled by setting the corresponding bit in the interrupt ---! enable register. The following bits are available: ---! - Bit 0: data received (receive buffer not empty) ---! - Bit 1: ready to send data (transmit buffer empty) -entity pp_soc_uart is - generic( - FIFO_DEPTH : natural := 64 --Unused - ); - port( - clk : in std_logic; - reset : in std_logic; - - -- UART ports: - txd : out std_logic; - rxd : in std_logic; - - -- Interrupt signal: - irq : out std_logic; - - -- Wishbone ports: - wb_adr_in : in std_logic_vector(11 downto 0); - wb_dat_in : in std_logic_vector( 7 downto 0); - wb_dat_out : out std_logic_vector( 7 downto 0); - wb_we_in : in std_logic; - wb_cyc_in : in std_logic; - wb_stb_in : in std_logic; - wb_ack_out : out std_logic - ); -end entity pp_soc_uart; - -architecture behaviour of pp_soc_uart is - - signal sample_clk_divisor : std_logic_vector(7 downto 0); - - -- IRQ enable signals: - signal irq_recv_enable, irq_tx_ready_enable : std_logic := '0'; - - -- Wishbone signals: - type wb_state_type is (IDLE, WRITE_ACK, READ_ACK); - signal wb_state : wb_state_type; - signal wb_ack : std_logic; --! Wishbone acknowledge signal - -begin - - wb_ack_out <= wb_ack and wb_cyc_in and wb_stb_in; - - -- For the sim console, the transmit buffer is always empty, so always - -- interrupt if enabled. No recieve interrupt. - irq <= irq_tx_ready_enable; - - wishbone: process(clk) - variable sim_tmp : std_logic_vector(63 downto 0); - begin - if rising_edge(clk) then - if reset = '1' then - wb_ack <= '0'; - wb_state <= IDLE; - sample_clk_divisor <= (others => '0'); - irq_recv_enable <= '0'; - irq_tx_ready_enable <= '0'; - else - case wb_state is - when IDLE => - if wb_cyc_in = '1' and wb_stb_in = '1' then - if wb_we_in = '1' then -- Write to register - if wb_adr_in(11 downto 0) = x"000" then - sim_console_write(x"00000000000000" & wb_dat_in); - elsif wb_adr_in(11 downto 0) = x"018" then - sample_clk_divisor <= wb_dat_in; - elsif wb_adr_in(11 downto 0) = x"020" then - irq_recv_enable <= wb_dat_in(0); - irq_tx_ready_enable <= wb_dat_in(1); - end if; - wb_ack <= '1'; - wb_state <= WRITE_ACK; - else -- Read from register - if wb_adr_in(11 downto 0) = x"008" then - sim_console_read(sim_tmp); - wb_dat_out <= sim_tmp(7 downto 0); - elsif wb_adr_in(11 downto 0) = x"010" then - sim_console_poll(sim_tmp); - wb_dat_out <= "00000" & sim_tmp(0) & '1' & not sim_tmp(0); - elsif wb_adr_in(11 downto 0) = x"018" then - wb_dat_out <= sample_clk_divisor; - elsif wb_adr_in(11 downto 0) = x"020" then - wb_dat_out <= (0 => irq_recv_enable, - 1 => irq_tx_ready_enable, - others => '0'); - else - wb_dat_out <= (others => '0'); - end if; - wb_ack <= '1'; - wb_state <= READ_ACK; - end if; - end if; - when WRITE_ACK|READ_ACK => - if wb_stb_in = '0' then - wb_ack <= '0'; - wb_state <= IDLE; - end if; - end case; - end if; - end if; - end process wishbone; - -end architecture behaviour; diff --git a/soc.vhdl b/soc.vhdl index 8c0401a..ddaac14 100644 --- a/soc.vhdl +++ b/soc.vhdl @@ -71,7 +71,6 @@ entity soc is SPI_BOOT_CLOCKS : boolean := true; LOG_LENGTH : natural := 512; HAS_LITEETH : boolean := false; - UART0_IS_16550 : boolean := true; HAS_UART1 : boolean := false; ICACHE_NUM_LINES : natural := 64; ICACHE_NUM_WAYS : natural := 2; @@ -244,6 +243,8 @@ architecture behaviour of soc is SLAVE_IO_NONE); signal slave_io_dbg : slave_io_type; + signal uart0_irq_l : std_ulogic; + function wishbone_widen_data(wb : wb_io_master_out) return wishbone_master_out is variable wwb : wishbone_master_out; begin @@ -737,7 +738,6 @@ begin SPI_FLASH_OFFSET => SPI_FLASH_OFFSET, HAS_LITEETH => HAS_LITEETH, HAS_SD_CARD => HAS_SD_CARD, - UART0_IS_16550 => UART0_IS_16550, HAS_UART1 => HAS_UART1 ) port map( @@ -750,74 +750,41 @@ begin soc_reset => open -- XXX TODO ); - -- -- UART0 - -- - -- Either potato (legacy) or 16550 - -- - uart0_pp: if not UART0_IS_16550 generate - uart0: entity work.pp_soc_uart - generic map( - FIFO_DEPTH => 32 - ) - port map( - clk => system_clk, - reset => rst_uart, - txd => uart0_txd, - rxd => uart0_rxd, - irq => uart0_irq, - wb_adr_in => wb_uart0_in.adr(11 downto 0), - wb_dat_in => wb_uart0_in.dat(7 downto 0), - wb_dat_out => uart0_dat8, - wb_cyc_in => wb_uart0_in.cyc, - wb_stb_in => wb_uart0_in.stb, - wb_we_in => wb_uart0_in.we, - wb_ack_out => wb_uart0_out.ack - ); - end generate; + uart0: uart_top + port map ( + wb_clk_i => system_clk, + wb_rst_i => rst_uart, + wb_adr_i => wb_uart0_in.adr(4 downto 2), + wb_dat_i => wb_uart0_in.dat(7 downto 0), + wb_dat_o => uart0_dat8, + wb_we_i => wb_uart0_in.we, + wb_stb_i => wb_uart0_in.stb, + wb_cyc_i => wb_uart0_in.cyc, + wb_ack_o => wb_uart0_out.ack, + int_o => uart0_irq_l, + stx_pad_o => uart0_txd, + srx_pad_i => uart0_rxd, + rts_pad_o => open, + cts_pad_i => '1', + dtr_pad_o => open, + dsr_pad_i => '1', + ri_pad_i => '0', + dcd_pad_i => '1' + ); - uart0_16550 : if UART0_IS_16550 generate - signal irq_l : std_ulogic; + -- Add a register on the irq out, helps timing + uart0_irq_latch: process(system_clk) begin - uart0: uart_top - port map ( - wb_clk_i => system_clk, - wb_rst_i => rst_uart, - wb_adr_i => wb_uart0_in.adr(4 downto 2), - wb_dat_i => wb_uart0_in.dat(7 downto 0), - wb_dat_o => uart0_dat8, - wb_we_i => wb_uart0_in.we, - wb_stb_i => wb_uart0_in.stb, - wb_cyc_i => wb_uart0_in.cyc, - wb_ack_o => wb_uart0_out.ack, - int_o => irq_l, - stx_pad_o => uart0_txd, - srx_pad_i => uart0_rxd, - rts_pad_o => open, - cts_pad_i => '1', - dtr_pad_o => open, - dsr_pad_i => '1', - ri_pad_i => '0', - dcd_pad_i => '1' - ); - - -- Add a register on the irq out, helps timing - uart0_irq_latch: process(system_clk) - begin - if rising_edge(system_clk) then - uart0_irq <= irq_l; - end if; - end process; - end generate; + if rising_edge(system_clk) then + uart0_irq <= uart0_irq_l; + end if; + end process; wb_uart0_out.dat <= x"000000" & uart0_dat8; wb_uart0_out.stall <= not wb_uart0_out.ack; - -- -- UART1 - -- - -- Always 16550 if it exists - -- uart1: if HAS_UART1 generate signal irq_l : std_ulogic; begin diff --git a/syscon.vhdl b/syscon.vhdl index 2f8bd47..abef925 100644 --- a/syscon.vhdl +++ b/syscon.vhdl @@ -19,7 +19,6 @@ entity syscon is SPI_FLASH_OFFSET : integer; HAS_LITEETH : boolean; HAS_SD_CARD : boolean; - UART0_IS_16550 : boolean; HAS_UART1 : boolean ); port ( @@ -88,7 +87,7 @@ architecture behaviour of syscon is -- UART0/1 info registers bits -- -- 0 ..31 : UART clock freq (in HZ) - -- 32 : UART is 16550 (otherwise pp) + -- 32 : UART is 16550 -- -- Ctrl register @@ -160,7 +159,7 @@ begin SYS_REG_CTRL_BITS-1 downto 0 => reg_ctrl); -- UART info registers read composition - uinfo_16550 <= '1' when UART0_IS_16550 else '0'; + uinfo_16550 <= '1'; uinfo_freq <= std_ulogic_vector(to_unsigned(CLK_FREQ, 32)); reg_uart0info <= (32 => uinfo_16550, 31 downto 0 => uinfo_freq,