spi_rxtx.vhdl spi_flash_ctrl.vhdl
-soc_sim_files = $(soc_files) sim_console.vhdl sim_uart.vhdl sim_bram_helpers.vhdl \
+soc_sim_files = $(soc_files) sim_console.vhdl sim_pp_uart.vhdl sim_bram_helpers.vhdl \
sim_bram.vhdl sim_jtag_socket.vhdl sim_jtag.vhdl dmi_dtm_xilinx.vhdl
soc_sim_c_files = sim_vhpi_c.c sim_bram_helpers_c.c sim_console_c.c \
"dmi_dtm" : "dmi_dtm_xilinx.vhdl",
"clock_generator" : "fpga/clk_gen_bypass.vhd",
"main_bram" : "sim_bram.vhdl",
- "pp_soc_uart" : "sim_uart.vhdl"
+ "pp_soc_uart" : "sim_pp_uart.vhdl"
}
if synth:
--- /dev/null
+-- 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;
+++ /dev/null
--- 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;