URL
https://opencores.org/ocsvn/potato/potato/trunk
Subversion Repositories potato
Compare Revisions
- This comparison shows the changes necessary to convert path
/potato/trunk
- from Rev 6 to Rev 7
- ↔ Reverse comparison
Rev 6 → Rev 7
/soc/pp_soc_gpio.vhd
0,0 → 1,95
-- The Potato Processor - A simple processor for FPGAs |
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net> |
-- Report bugs and issues on <https://github.com/skordal/potato/issues> |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
--! @brief Generic Wishbone GPIO Module. |
--! The following registers are defined: |
--! * 0: Input values, one bit per GPIO (read-only) |
--! * 1: Output values, one bit per GPIO (read/write) |
--! * 2: Direction register, 0 means input, 1 means output. |
entity pp_soc_gpio is |
generic( |
NUM_GPIOS : natural := 32 |
); |
port( |
clk : in std_logic; |
reset : in std_logic; |
|
-- GPIO interface: |
gpio : inout std_logic_vector(NUM_GPIOS - 1 downto 0); |
|
-- Wishbone interface: |
wb_adr_in : in std_logic_vector( 1 downto 0); |
wb_dat_in : in std_logic_vector(31 downto 0); |
wb_dat_out : out std_logic_vector(31 downto 0); |
wb_cyc_in : in std_logic; |
wb_stb_in : in std_logic; |
wb_we_in : in std_logic; |
wb_ack_out : out std_logic |
); |
end entity pp_soc_gpio; |
|
architecture behaviour of pp_soc_gpio is |
|
signal direction_register : std_logic_vector(NUM_GPIOS - 1 downto 0); |
signal output_register : std_logic_vector(NUM_GPIOS - 1 downto 0); |
signal input_register : std_logic_vector(NUM_GPIOS - 1 downto 0); |
|
signal ack : std_logic := '0'; |
|
begin |
|
assert NUM_GPIOS > 0 and NUM_GPIOS <= 32 |
report "Only a number between 1 and 32 (inclusive) GPIOs are supported!" |
severity FAILURE; |
|
io_setup: for i in 0 to NUM_GPIOS - 1 generate |
gpio(i) <= 'Z' when direction_register(i) = '0' else output_register(i); |
input_register(i) <= gpio(i) when direction_register(i) = '0' else '0'; |
end generate; |
|
wb_ack_out <= ack and wb_cyc_in and wb_stb_in; |
|
wishbone: process(clk) |
begin |
if rising_edge(clk) then |
if reset = '1' then |
direction_register <= (others => '0'); |
output_register <= (others => '0'); |
wb_dat_out <= (others => '0'); |
ack <= '0'; |
else |
if wb_cyc_in = '1' and wb_stb_in = '1' and ack = '0' then |
if wb_we_in = '1' then |
case wb_adr_in is |
when b"01" => |
output_register <= wb_dat_in(NUM_GPIOS - 1 downto 0); |
when b"10" => |
direction_register <= wb_dat_in(NUM_GPIOS - 1 downto 0); |
when others => |
end case; |
ack <= '1'; |
else |
case wb_adr_in is |
when b"00" => |
wb_dat_out <= std_logic_vector(resize(unsigned(input_register), wb_dat_out'length)); |
when b"01" => |
wb_dat_out <= std_logic_vector(resize(unsigned(output_register), wb_dat_out'length)); |
when b"10" => |
wb_dat_out <= std_logic_vector(resize(unsigned(direction_register), wb_dat_out'length)); |
when others => |
end case; |
ack <= '1'; |
end if; |
elsif wb_stb_in = '0' then |
ack <= '0'; |
end if; |
end if; |
end if; |
end process wishbone; |
|
end architecture behaviour; |
/soc/pp_soc_timer.vhd
0,0 → 1,99
-- The Potato Processor - A simple processor for FPGAs |
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net> |
-- Report bugs and issues on <https://github.com/skordal/potato/issues> |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
--! @brief Simple timer module for generating periodic interrupts. |
--! The following registers are defined: |
--! * 0: Control register. The bits are: |
--! - 0: Run - set to '1' to enable the counter |
--! - 1: Clear - set to '1' to clear the counter after a comparison match or just to reset it |
--! * 1: Compare register, set this to the value where an interrupt should be generated. |
--! * 2: Counter register, should only be read, but can be written if you want to. |
entity pp_soc_timer is |
port( |
clk : in std_logic; |
reset : in std_logic; |
|
-- Timer interrupt: |
irq : out std_logic; |
|
-- Wishbone interface: |
wb_adr_in : in std_logic_vector( 1 downto 0); |
wb_dat_in : in std_logic_vector(31 downto 0); |
wb_dat_out : out std_logic_vector(31 downto 0); |
wb_cyc_in : in std_logic; |
wb_stb_in : in std_logic; |
wb_we_in : in std_logic; |
wb_ack_out : out std_logic |
); |
end entity; |
|
architecture behaviour of pp_soc_timer is |
signal ctrl_run : std_logic; |
|
signal counter : std_logic_vector(31 downto 0); |
signal compare : std_logic_vector(31 downto 0); |
|
-- Wishbone acknowledge signal: |
signal ack : std_logic; |
begin |
|
wb_ack_out <= ack and wb_cyc_in and wb_stb_in; |
irq <= '1' when counter = compare else '0'; |
|
timer: process(clk) |
begin |
if rising_edge(clk) then |
if reset = '1' then |
wb_dat_out <= (others => '0'); |
ack <= '0'; |
|
ctrl_run <= '0'; |
counter <= (others => '0'); |
compare <= (others => '1'); |
else |
if ctrl_run = '1' and counter /= compare then |
counter <= std_logic_vector(unsigned(counter) + 1); |
end if; |
|
if wb_cyc_in = '1' and wb_stb_in = '1' and ack = '0' then |
if wb_we_in = '1' then |
case wb_adr_in is |
when b"00" => -- Write control register |
ctrl_run <= wb_dat_in(0); |
if wb_dat_in(1) = '1' then |
counter <= (others => '0'); |
end if; |
when b"01" => -- Write compare register |
compare <= wb_dat_in; |
when b"10" => -- Write count register |
counter <= wb_dat_in; |
when b"11" => -- Unused register |
when others => |
end case; |
ack <= '1'; |
else |
case wb_adr_in is |
when b"00" => -- Read control register |
wb_dat_out <= (0 => ctrl_run, others => '0'); |
when b"01" => -- Read compare register |
wb_dat_out <= compare; |
when b"10" => -- Read count register |
wb_dat_out <= counter; |
when b"11" => -- Unused register |
when others => |
end case; |
ack <= '1'; |
end if; |
elsif wb_stb_in = '0' then |
ack <= '0'; |
end if; |
end if; |
end if; |
end process timer; |
|
end architecture behaviour; |
/soc/pp_soc_dummy.vhd
0,0 → 1,56
-- The Potato Processor - A simple processor for FPGAs |
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net> |
-- Report bugs and issues on <https://github.com/skordal/potato/issues> |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
--! @brief Dummy module for an SoC implementation. |
--! Reads returns whatever was last written into the module. |
entity pp_soc_dummy is |
port( |
clk : in std_logic; |
reset : in std_logic; |
|
-- Wishbone signals: |
wb_dat_in : in std_logic_vector(31 downto 0); |
wb_dat_out : out std_logic_vector(31 downto 0); |
wb_cyc_in : in std_logic; |
wb_stb_in : in std_logic; |
wb_we_in : in std_logic; |
wb_ack_out : out std_logic |
); |
end entity pp_soc_dummy; |
|
architecture behaviour of pp_soc_dummy is |
|
signal reg : std_logic_vector(31 downto 0); |
signal ack : std_logic; |
|
begin |
|
wb_ack_out <= ack and wb_cyc_in and wb_stb_in; |
|
wishbone: process(clk) |
begin |
if rising_edge(clk) then |
if reset = '1' then |
reg <= (others => '0'); |
ack <= '0'; |
else |
if wb_cyc_in = '1' and wb_stb_in = '1' and ack = '0' then |
if wb_we_in = '1' then |
reg <= wb_dat_in; |
ack <= '1'; |
else |
wb_dat_out <= reg; |
ack <= '1'; |
end if; |
elsif wb_stb_in = '0' then |
ack <= '0'; |
end if; |
end if; |
end if; |
end process wishbone; |
|
end architecture behaviour; |
/soc/pp_soc_uart.vhd
0,0 → 1,333
-- The Potato Processor - A simple processor for FPGAs |
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net> |
-- Report bugs and issues on <https://github.com/skordal/potato/issues> |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
--! @brief Simple UART module. |
--! The following registers are defined: |
--! 0 - Transmit data register (write-only) |
--! 1 - Receive data register (read-only) |
--! 2 - Status register; (read-only) |
--! - Bit 0: data in receive buffer |
--! - Bit 1: no data in transmit buffer |
--! - Bit 2: receive buffer full |
--! - Bit 3: transmit buffer full |
--! 3 - Control register, currently unused. |
entity pp_soc_uart is |
generic( |
FIFO_DEPTH : natural := 64; --! Depth of the input and output FIFOs. |
SAMPLE_CLK_DIVISOR : natural := 54 --! Divisor used to obtain the sample clock, f_clk / (16 * baudrate). |
); |
port( |
clk : in std_logic; |
reset : in std_logic; |
|
-- UART ports: |
txd : out std_logic; |
rxd : in std_logic; |
|
-- Interrupt signals: |
irq_send_buffer_empty : out std_logic; |
irq_data_received : out std_logic; |
|
-- Wishbone ports: |
wb_adr_in : in std_logic_vector(1 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; |
|
-- UART sample clock signals: |
signal sample_clk : std_logic; |
|
subtype sample_clk_counter_type is natural range 0 to SAMPLE_CLK_DIVISOR - 1; |
signal sample_clk_counter : sample_clk_counter_type := 0; |
|
-- UART receive process signals: |
type rx_state_type is (IDLE, RECEIVE, 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; |
|
-- 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'; |
|
-- 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 |
|
irq_send_buffer_empty <= send_buffer_empty; |
irq_data_received <= not recv_buffer_empty; |
|
---------- UART receive ---------- |
|
recv_buffer_input <= rx_byte; |
|
uart_receive: process(clk) |
begin |
if rising_edge(clk) then |
if reset = '1' then |
rx_state <= IDLE; |
else |
case rx_state is |
when IDLE => |
if sample_clk = '1' and rxd = '0' then |
rx_sample_value <= rx_sample_counter; |
rx_current_bit <= 0; |
rx_state <= RECEIVE; |
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) <= rxd; |
rx_current_bit <= rx_current_bit + 1; |
else |
rx_byte(rx_current_bit) <= rxd; |
rx_state <= STOPBIT; |
|
if recv_buffer_full = '0' then |
recv_buffer_push <= '1'; |
end if; |
end if; |
end if; |
when STOPBIT => |
recv_buffer_push <= '0'; |
|
if sample_clk = '1' and rx_sample_counter = rx_sample_value then |
rx_state <= IDLE; |
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 |
txd <= '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 |
txd <= '0'; |
send_buffer_pop <= '1'; |
tx_current_bit <= 0; |
tx_state <= TRANSMIT; |
elsif uart_tx_clk = '1' then |
txd <= '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 |
txd <= tx_byte(tx_current_bit); |
tx_state <= STOPBIT; |
elsif uart_tx_clk = '1' then |
txd <= tx_byte(tx_current_bit); |
tx_current_bit <= tx_current_bit + 1; |
end if; |
when STOPBIT => |
if uart_tx_clk = '1' then |
txd <= '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 <= 0; |
sample_clk <= '0'; |
else |
if sample_clk_counter = SAMPLE_CLK_DIVISOR - 1 then |
sample_clk_counter <= 0; |
sample_clk <= '1'; |
else |
sample_clk_counter <= sample_clk_counter + 1; |
sample_clk <= '0'; |
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 ---------- |
|
wb_ack_out <= wb_ack and wb_cyc_in and wb_stb_in; |
|
wishbone: process(clk) |
begin |
if rising_edge(clk) then |
if reset = '1' then |
wb_ack <= '0'; |
wb_state <= IDLE; |
send_buffer_push <= '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 = b"00" then |
send_buffer_input <= wb_dat_in; |
send_buffer_push <= '1'; |
wb_ack <= '1'; |
wb_state <= WRITE_ACK; |
else -- Invalid write, just ack and ignore |
wb_ack <= '1'; |
wb_state <= WRITE_ACK; |
end if; |
else -- Read from register |
if wb_adr_in = b"01" then |
recv_buffer_pop <= '1'; |
wb_state <= READ_ACK; |
elsif wb_adr_in = b"10" then |
wb_dat_out <= x"0" & send_buffer_full & recv_buffer_full & send_buffer_empty & not recv_buffer_empty; |
wb_ack <= '1'; |
wb_state <= READ_ACK; |
else |
wb_dat_out <= (others => '0'); |
wb_ack <= '1'; |
wb_state <= READ_ACK; |
end if; |
end if; |
end if; |
when WRITE_ACK => |
send_buffer_push <= '0'; |
|
if wb_stb_in = '0' then |
wb_ack <= '0'; |
wb_state <= IDLE; |
end if; |
when READ_ACK => |
if recv_buffer_pop = '1' then |
wb_ack <= '1'; |
recv_buffer_pop <= '0'; |
wb_dat_out <= recv_buffer_output; |
end if; |
|
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; |
/testbenches/tb_soc_uart.vhd
0,0 → 1,95
-- The Potato Processor - A simple processor for FPGAs |
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net> |
-- Report bugs and issues on <https://github.com/skordal/potato/issues> |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
entity tb_soc_uart is |
end entity tb_soc_uart; |
|
architecture testbench of tb_soc_uart is |
|
-- Clock signal: |
signal clk : std_logic := '0'; |
constant clk_period : time := 10 ns; |
|
-- Reset signal: |
signal reset : std_logic := '1'; |
|
-- UART ports: |
signal txd : std_logic; |
signal rxd : std_logic := '1'; |
|
-- interrupt signals: |
signal irq_send_buffer_empty : std_logic; |
signal irq_data_received : std_logic; |
|
-- Wishbone ports: |
signal wb_adr_in : std_logic_vector(1 downto 0) := (others => '0'); |
signal wb_dat_in : std_logic_vector(7 downto 0) := (others => '0'); |
signal wb_dat_out : std_logic_vector(7 downto 0); |
signal wb_we_in : std_logic := '0'; |
signal wb_cyc_in : std_logic := '0'; |
signal wb_stb_in : std_logic := '0'; |
signal wb_ack_out : std_logic; |
|
begin |
|
uut: entity work.pp_soc_uart |
port map( |
clk => clk, |
reset => reset, |
txd => txd, |
rxd => rxd, |
irq_send_buffer_empty => irq_send_buffer_empty, |
irq_data_received => irq_data_received, |
wb_adr_in => wb_adr_in, |
wb_dat_in => wb_dat_in, |
wb_dat_out => wb_dat_out, |
wb_we_in => wb_we_in, |
wb_cyc_in => wb_cyc_in, |
wb_stb_in => wb_stb_in, |
wb_ack_out => wb_ack_out |
); |
|
-- Set up an internal loopback: |
rxd <= txd; |
|
clock: process |
begin |
clk <= '1'; |
wait for clk_period / 2; |
clk <= '0'; |
wait for clk_period / 2; |
end process clock; |
|
stimulus: process |
begin |
wait for clk_period * 2; |
reset <= '0'; |
|
-- Write a 'P' (for Potato the Processor) to the UART: |
wb_adr_in <= b"00"; |
wb_dat_in <= x"50"; |
wb_we_in <= '1'; |
wb_cyc_in <= '1'; |
wb_stb_in <= '1'; |
|
wait until wb_ack_out = '1'; |
wait for clk_period; |
wb_stb_in <= '0'; |
wait for clk_period; |
|
-- Write an 'o': |
wb_dat_in <= x"6f"; |
wb_stb_in <= '1'; |
wait until wb_ack_out = '1'; |
wait for clk_period; |
wb_stb_in <= '0'; |
wait for clk_period; |
|
wait; |
end process stimulus; |
|
end architecture testbench; |
/testbenches/tb_soc_gpio.vhd
0,0 → 1,91
-- The Potato Processor - A simple processor for FPGAs |
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net> |
-- Report bugs and issues on <https://github.com/skordal/potato/issues> |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
entity tb_soc_gpio is |
end entity tb_soc_gpio; |
|
architecture testbench of tb_soc_gpio is |
|
-- Clock signal: |
signal clk : std_logic := '0'; |
constant clk_period : time := 10 ns; |
|
-- Reset signal: |
signal reset : std_logic := '1'; |
|
-- GPIOs: |
signal gpio : std_logic_vector(31 downto 0); |
|
-- Wishbone bus: |
signal wb_adr_in : std_logic_vector( 1 downto 0) := (others => '0'); |
signal wb_dat_in : std_logic_vector(31 downto 0) := (others => '0'); |
signal wb_dat_out : std_logic_vector(31 downto 0); |
signal wb_cyc_in : std_logic := '0'; |
signal wb_stb_in : std_logic := '0'; |
signal wb_we_in : std_logic := '0'; |
signal wb_ack_out : std_logic; |
begin |
|
uut: entity work.pp_soc_gpio |
generic map( |
NUM_GPIOS => 32 |
) port map( |
clk => clk, |
reset => reset, |
gpio => gpio, |
wb_adr_in => wb_adr_in, |
wb_dat_in => wb_dat_in, |
wb_dat_out => wb_dat_out, |
wb_cyc_in => wb_cyc_in, |
wb_stb_in => wb_stb_in, |
wb_we_in => wb_we_in, |
wb_ack_out => wb_ack_out |
); |
|
clock: process |
begin |
clk <= '1'; |
wait for clk_period / 2; |
clk <= '0'; |
wait for clk_period / 2; |
end process clock; |
|
stimulus: process |
begin |
wait for clk_period * 2; |
reset <= '0'; |
|
-- Set the upper half of the GPIOs as inputs, the rest as outputs: |
wb_dat_in <= x"0000ffff"; |
wb_adr_in <= b"10"; |
wb_we_in <= '1'; |
wb_cyc_in <= '1'; |
wb_stb_in <= '1'; |
wait until wb_ack_out = '1'; |
wait for clk_period; |
wb_stb_in <= '0'; |
wb_cyc_in <= '0'; |
wb_we_in <= '0'; |
wait for clk_period; |
|
-- Set the outputs to aa, see if the upper half gets ignored correctly: |
wb_dat_in <= x"aaaaaaaa"; |
wb_adr_in <= b"01"; |
wb_we_in <= '1'; |
wb_cyc_in <= '1'; |
wb_stb_in <= '1'; |
wait until wb_ack_out = '1'; |
wait for clk_period; |
wb_stb_in <= '0'; |
wb_cyc_in <= '0'; |
wb_we_in <= '0'; |
wait for clk_period; |
|
wait; |
end process stimulus; |
|
end architecture testbench; |
/testbenches/tb_soc_timer.vhd
0,0 → 1,108
-- The Potato Processor - A simple processor for FPGAs |
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net> |
-- Report bugs and issues on <https://github.com/skordal/potato/issues> |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
entity tb_soc_timer is |
end entity tb_soc_timer; |
|
architecture behaviour of tb_soc_timer is |
|
-- Clock signal: |
signal clk : std_logic := '0'; |
constant clk_period : time := 10 ns; |
|
-- Reset signal: |
signal reset : std_logic := '1'; |
|
-- IRQ signal: |
signal irq : std_logic; |
|
-- Wishbone interface: |
signal wb_adr_in : std_logic_vector(1 downto 0) := (others => '0'); |
signal wb_dat_in : std_logic_vector(31 downto 0) := (others => '0'); |
signal wb_dat_out : std_logic_vector(31 downto 0); |
signal wb_cyc_in : std_logic := '0'; |
signal wb_stb_in : std_logic := '0'; |
signal wb_we_in : std_logic := '0'; |
signal wb_ack_out : std_logic; |
|
begin |
|
uut: entity work.pp_soc_timer |
port map( |
clk => clk, |
reset => reset, |
irq => irq, |
wb_adr_in => wb_adr_in, |
wb_dat_in => wb_dat_in, |
wb_dat_out => wb_dat_out, |
wb_cyc_in => wb_cyc_in, |
wb_stb_in => wb_stb_in, |
wb_we_in => wb_we_in, |
wb_ack_out => wb_ack_out |
); |
|
clock: process |
begin |
clk <= '1'; |
wait for clk_period / 2; |
clk <= '0'; |
wait for clk_period / 2; |
end process clock; |
|
stimulus: process |
begin |
wait for clk_period * 2; |
reset <= '0'; |
|
wait for clk_period; |
|
-- Set the compare register to 50: |
wb_cyc_in <= '1'; |
wb_stb_in <= '1'; |
wb_adr_in <= b"01"; |
wb_dat_in <= x"00000032"; |
wb_we_in <= '1'; |
wait until wb_ack_out = '1'; |
wait for clk_period; |
|
wb_stb_in <= '0'; |
wait for clk_period; |
|
-- Start the timer: |
wb_stb_in <= '1'; |
wb_adr_in <= b"00"; |
wb_dat_in <= x"00000003"; |
wait until wb_ack_out = '1'; |
wait for clk_period; |
|
wb_stb_in <= '0'; |
wb_cyc_in <= '0'; |
wb_we_in <= '0'; |
wait for clk_period; |
|
-- Wait for the interrupt: |
wait until irq = '1'; |
wait for clk_period; |
|
-- Reset the interrupt: |
wb_cyc_in <= '1'; |
wb_stb_in <= '1'; |
wb_we_in <= '1'; |
wb_adr_in <= b"00"; |
wb_dat_in <= x"00000003"; |
wait until wb_ack_out = '1'; |
wait for clk_period; |
|
wb_stb_in <= '0'; |
wb_cyc_in <= '0'; |
wb_we_in <= '0'; |
wait for clk_period; |
|
wait; |
end process stimulus; |
|
end architecture behaviour; |
/example/imem_wrapper.vhd
0,0 → 1,68
-- Practical Test Application for the Potato Processor |
-- (c) Kristian Klomsten Skordal 2015 <kristian.skordal@wafflemail.net> |
-- Report bugs and issues on <https://github.com/skordal/potato-test/issues> |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
entity imem_wrapper is |
port( |
clk : in std_logic; |
reset : in std_logic; |
|
-- Wishbone interface: |
wb_adr_in : in std_logic_vector(12 downto 0); |
wb_dat_out : out std_logic_vector(31 downto 0); |
wb_cyc_in : in std_logic; |
wb_stb_in : in std_logic; |
wb_ack_out : out std_logic |
); |
end entity imem_wrapper; |
|
architecture behaviour of imem_wrapper is |
|
type wb_state is (IDLE, READ_ACK); |
signal state : wb_state := IDLE; |
|
signal address : std_logic_vector(10 downto 0); |
signal data : std_logic_vector(31 downto 0); |
|
signal ack : std_logic := '0'; |
|
begin |
|
imem: entity work.instruction_rom |
port map( |
clka => clk, |
addra => address, |
douta => wb_dat_out |
); |
|
wb_ack_out <= ack and wb_cyc_in and wb_stb_in; |
|
wishbone: process(clk) |
begin |
if rising_edge(clk) then |
if reset = '1' then |
ack <= '0'; |
state <= IDLE; |
else |
case state is |
when IDLE => |
if wb_cyc_in = '1' and wb_stb_in = '1' then |
address <= wb_adr_in(12 downto 2); |
state <= READ_ACK; |
end if; |
when READ_ACK => |
if ack = '0' then |
ack <= '1'; |
elsif wb_stb_in = '0' then |
ack <= '0'; |
state <= IDLE; |
end if; |
end case; |
end if; |
end if; |
end process wishbone; |
|
end architecture behaviour; |
/example/toplevel.vhd
0,0 → 1,370
-- Practical Test Application for the Potato Processor |
-- (c) Kristian Klomsten Skordal 2015 <kristian.skordal@wafflemail.net> |
-- Report bugs and issues on <https://github.com/skordal/potato-test/issues> |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
entity toplevel is |
port( |
clk : in std_logic; -- System clock, 100 MHz |
reset_n : in std_logic; -- CPU reset signal, active low |
|
-- External interrupt input: |
external_interrupt : in std_logic; |
|
-- GPIO pins, must be inout to use with the GPIO module: |
switches : inout std_logic_vector(15 downto 0); |
leds : inout std_logic_vector(15 downto 0); |
|
-- UART1 (host) pins: |
uart_txd : out std_logic; |
uart_rxd : in std_logic |
); |
end entity toplevel; |
|
architecture behaviour of toplevel is |
signal system_clk : std_logic; |
signal timer_clk : std_logic; |
|
-- Active high reset signal: |
signal reset : std_logic; |
|
-- IRQs: |
signal irq : std_logic_vector(7 downto 0); |
signal uart_irq_rts, uart_irq_recv : std_logic; |
signal timer_irq : std_logic; |
|
-- Processor wishbone interface: |
signal p_adr_out : std_logic_vector(31 downto 0); |
signal p_dat_out : std_logic_vector(31 downto 0); |
signal p_dat_in : std_logic_vector(31 downto 0); |
signal p_sel_out : std_logic_vector( 3 downto 0); |
signal p_we_out : std_logic; |
signal p_cyc_out, p_stb_out : std_logic; |
signal p_ack_in : std_logic; |
|
-- Instruction memory wishbone interface: |
signal imem_adr_in : std_logic_vector(12 downto 0); |
signal imem_dat_out : std_logic_vector(31 downto 0); |
signal imem_cyc_in, imem_stb_in : std_logic; |
signal imem_ack_out : std_logic; |
|
-- Data memory wishbone interface: |
signal dmem_adr_in : std_logic_vector(12 downto 0); |
signal dmem_dat_in : std_logic_vector(31 downto 0); |
signal dmem_dat_out : std_logic_vector(31 downto 0); |
signal dmem_sel_in : std_logic_vector( 3 downto 0); |
signal dmem_we_in : std_logic; |
signal dmem_cyc_in, dmem_stb_in : std_logic; |
signal dmem_ack_out : std_logic; |
|
-- GPIO module I (switches) wishbone interface: |
signal gpio1_adr_in : std_logic_vector(1 downto 0); |
signal gpio1_dat_in : std_logic_vector(31 downto 0); |
signal gpio1_dat_out : std_logic_vector(31 downto 0); |
signal gpio1_we_in : std_logic; |
signal gpio1_cyc_in, gpio1_stb_in : std_logic; |
signal gpio1_ack_out : std_logic; |
|
-- GPIO module II (LEDs) wishbone interface: |
signal gpio2_adr_in : std_logic_vector(1 downto 0); |
signal gpio2_dat_in : std_logic_vector(31 downto 0); |
signal gpio2_dat_out : std_logic_vector(31 downto 0); |
signal gpio2_we_in : std_logic; |
signal gpio2_cyc_in, gpio2_stb_in : std_logic; |
signal gpio2_ack_out : std_logic; |
|
-- UART module wishbone interface: |
signal uart_adr_in : std_logic_vector(1 downto 0); |
signal uart_dat_in : std_logic_vector(7 downto 0); |
signal uart_dat_out : std_logic_vector(7 downto 0); |
signal uart_we_in : std_logic; |
signal uart_cyc_in, uart_stb_in : std_logic; |
signal uart_ack_out : std_logic; |
|
-- Timer module wishbone interface: |
signal timer_adr_in : std_logic_vector(1 downto 0); |
signal timer_dat_in : std_logic_vector(31 downto 0); |
signal timer_dat_out : std_logic_vector(31 downto 0); |
signal timer_we_in : std_logic; |
signal timer_cyc_in, timer_stb_in : std_logic; |
signal timer_ack_out : std_logic; |
|
-- Dummy module interface: |
signal dummy_dat_in : std_logic_vector(31 downto 0); |
signal dummy_dat_out : std_logic_vector(31 downto 0); |
signal dummy_we_in : std_logic; |
signal dummy_cyc_in, dummy_stb_in : std_logic; |
signal dummy_ack_out : std_logic; |
|
-- Address decoder signals: |
type ad_state_type is (IDLE, BUSY); |
signal ad_state : ad_state_type; |
|
type module_name is ( |
MODULE_IMEM, MODULE_DMEM, -- Memory modules |
MODULE_GPIO1, MODULE_GPIO2, -- GPIO modules |
MODULE_UART, -- UART module |
MODULE_TIMER, -- Timer module |
MODULE_DUMMY, -- Dummy module, used for invalid addresses |
MODULE_NONE -- Boring no-module mode, uses the dummy module |
); |
signal active_module : module_name; |
|
begin |
|
reset <= not reset_n; |
irq <= ( |
0 => external_interrupt, |
1 => uart_irq_rts, 2 => uart_irq_recv, |
5 => timer_irq, others => '0' |
); |
|
clkgen: entity work.clock_generator |
port map( |
clk => clk, |
system_clk => system_clk, |
timer_clk => timer_clk |
); |
|
processor: entity work.pp_potato |
port map( |
clk => system_clk, |
reset => reset, |
irq => irq, |
fromhost_data => (others => '0'), |
fromhost_updated => '0', |
tohost_data => open, |
tohost_updated => open, |
wb_adr_out => p_adr_out, |
wb_dat_out => p_dat_out, |
wb_dat_in => p_dat_in, |
wb_sel_out => p_sel_out, |
wb_we_out => p_we_out, |
wb_cyc_out => p_cyc_out, |
wb_stb_out => p_stb_out, |
wb_ack_in => p_ack_in |
); |
|
imem: entity work.imem_wrapper |
port map( |
clk => system_clk, |
reset => reset, |
wb_adr_in => imem_adr_in, |
wb_dat_out => imem_dat_out, |
wb_cyc_in => imem_cyc_in, |
wb_stb_in => imem_stb_in, |
wb_ack_out => imem_ack_out |
); |
|
dmem: entity work.pp_soc_memory |
generic map( |
MEMORY_SIZE => 8192 |
) port map( |
clk => system_clk, |
reset => reset, |
wb_adr_in => dmem_adr_in, |
wb_dat_in => dmem_dat_in, |
wb_dat_out => dmem_dat_out, |
wb_sel_in => dmem_sel_in, |
wb_we_in => dmem_we_in, |
wb_cyc_in => dmem_cyc_in, |
wb_stb_in => dmem_stb_in, |
wb_ack_out => dmem_ack_out |
); |
|
gpio1: entity work.pp_soc_gpio |
generic map( |
NUM_GPIOS => 16 |
) port map( |
clk => system_clk, |
reset => reset, |
gpio => switches, |
wb_adr_in => gpio1_adr_in, |
wb_dat_in => gpio1_dat_in, |
wb_dat_out => gpio1_dat_out, |
wb_cyc_in => gpio1_cyc_in, |
wb_stb_in => gpio1_stb_in, |
wb_we_in => gpio1_we_in, |
wb_ack_out => gpio1_ack_out |
); |
|
gpio2: entity work.pp_soc_gpio |
generic map( |
NUM_GPIOS => 16 |
) port map( |
clk => system_clk, |
reset => reset, |
gpio => leds, |
wb_adr_in => gpio2_adr_in, |
wb_dat_in => gpio2_dat_in, |
wb_dat_out => gpio2_dat_out, |
wb_cyc_in => gpio2_cyc_in, |
wb_stb_in => gpio2_stb_in, |
wb_we_in => gpio2_we_in, |
wb_ack_out => gpio2_ack_out |
); |
|
uart1: entity work.pp_soc_uart |
generic map( |
FIFO_DEPTH => 64, |
SAMPLE_CLK_DIVISOR => 27 |
) port map( |
clk => system_clk, |
reset => reset, |
txd => uart_txd, |
rxd => uart_rxd, |
irq_send_buffer_empty => uart_irq_rts, |
irq_data_received => uart_irq_recv, |
wb_adr_in => uart_adr_in, |
wb_dat_in => uart_dat_in, |
wb_dat_out => uart_dat_out, |
wb_cyc_in => uart_cyc_in, |
wb_stb_in => uart_stb_in, |
wb_we_in => uart_we_in, |
wb_ack_out => uart_ack_out |
); |
|
timer1: entity work.pp_soc_timer |
port map( |
clk => system_clk, |
reset => reset, |
irq => timer_irq, |
wb_adr_in => timer_adr_in, |
wb_dat_in => timer_dat_in, |
wb_dat_out => timer_dat_out, |
wb_cyc_in => timer_cyc_in, |
wb_stb_in => timer_stb_in, |
wb_we_in => timer_we_in, |
wb_ack_out => timer_ack_out |
); |
|
dummy: entity work.pp_soc_dummy |
port map( |
clk => system_clk, |
reset => reset, |
wb_dat_in => dummy_dat_in, |
wb_dat_out => dummy_dat_out, |
wb_cyc_in => dummy_cyc_in, |
wb_stb_in => dummy_stb_in, |
wb_we_in => dummy_we_in, |
wb_ack_out => dummy_ack_out |
); |
|
imem_cyc_in <= p_cyc_out when active_module = MODULE_IMEM else '0'; |
dmem_cyc_in <= p_cyc_out when active_module = MODULE_DMEM else '0'; |
gpio1_cyc_in <= p_cyc_out when active_module = MODULE_GPIO1 else '0'; |
gpio2_cyc_in <= p_cyc_out when active_module = MODULE_GPIO2 else '0'; |
uart_cyc_in <= p_cyc_out when active_module = MODULE_UART else '0'; |
timer_cyc_in <= p_cyc_out when active_module = MODULE_TIMER else '0'; |
dummy_cyc_in <= p_cyc_out when active_module = MODULE_DUMMY else '0'; |
|
imem_stb_in <= p_stb_out when active_module = MODULE_IMEM else '0'; |
dmem_stb_in <= p_stb_out when active_module = MODULE_DMEM else '0'; |
gpio1_stb_in <= p_stb_out when active_module = MODULE_GPIO1 else '0'; |
gpio2_stb_in <= p_stb_out when active_module = MODULE_GPIO2 else '0'; |
uart_stb_in <= p_stb_out when active_module = MODULE_UART else '0'; |
timer_stb_in <= p_stb_out when active_module = MODULE_TIMER else '0'; |
dummy_stb_in <= p_stb_out when active_module = MODULE_DUMMY else '0'; |
|
imem_adr_in <= p_adr_out(12 downto 0); |
dmem_adr_in <= p_adr_out(12 downto 0); |
gpio1_adr_in <= p_adr_out(3 downto 2); |
gpio2_adr_in <= p_adr_out(3 downto 2); |
uart_adr_in <= p_adr_out(3 downto 2); |
timer_adr_in <= p_adr_out(3 downto 2); |
|
dmem_dat_in <= p_dat_out; |
gpio1_dat_in <= p_dat_out; |
gpio2_dat_in <= p_dat_out; |
uart_dat_in <= p_dat_out(7 downto 0); |
timer_dat_in <= p_dat_out; |
dummy_dat_in <= p_dat_out; |
|
dmem_sel_in <= p_sel_out; |
|
gpio1_we_in <= p_we_out; |
gpio2_we_in <= p_we_out; |
dmem_we_in <= p_we_out; |
uart_we_in <= p_we_out; |
timer_we_in <= p_we_out; |
dummy_we_in <= p_we_out; |
|
address_decoder: process(system_clk) |
begin |
if rising_edge(system_clk) then |
if reset = '1' then |
ad_state <= IDLE; |
active_module <= MODULE_NONE; |
else |
case ad_state is |
when IDLE => |
if p_cyc_out = '1' and p_stb_out = '1' then |
if p_adr_out(31 downto 13) = b"0000000000000000000" then |
active_module <= MODULE_IMEM; |
ad_state <= BUSY; |
elsif p_adr_out(31 downto 13) = b"0000000000000000001" then -- 0x2000 |
active_module <= MODULE_DMEM; |
ad_state <= BUSY; |
elsif p_adr_out(31 downto 11) = b"000000000000000001000" then -- 0x4000 |
active_module <= MODULE_GPIO1; |
ad_state <= BUSY; |
elsif p_adr_out(31 downto 11) = b"000000000000000001001" then -- 0x4800 |
active_module <= MODULE_GPIO2; |
ad_state <= BUSY; |
elsif p_adr_out(31 downto 11) = b"000000000000000001010" then -- 0x5000 |
active_module <= MODULE_UART; |
ad_state <= BUSY; |
elsif p_adr_out(31 downto 11) = b"000000000000000001011" then -- 0x5800 |
active_module <= MODULE_TIMER; |
ad_state <= BUSY; |
else |
--active_module <= MODULE_NONE; |
active_module <= MODULE_DUMMY; |
ad_state <= BUSY; |
end if; |
end if; |
when BUSY => |
if p_cyc_out = '0' then |
active_module <= MODULE_NONE; |
ad_state <= IDLE; |
end if; |
end case; |
end if; |
end if; |
end process address_decoder; |
|
module_mux: process(active_module, imem_ack_out, imem_dat_out, dmem_ack_out, dmem_dat_out, |
gpio1_ack_out, gpio1_dat_out, gpio2_ack_out, gpio2_dat_out, uart_ack_out, uart_dat_out, |
timer_ack_out, timer_dat_out, dummy_ack_out, dummy_dat_out) |
begin |
case active_module is |
when MODULE_IMEM => |
p_ack_in <= imem_ack_out; |
p_dat_in <= imem_dat_out; |
when MODULE_DMEM => |
p_ack_in <= dmem_ack_out; |
p_dat_in <= dmem_dat_out; |
when MODULE_GPIO1 => |
p_ack_in <= gpio1_ack_out; |
p_dat_in <= gpio1_dat_out; |
when MODULE_GPIO2 => |
p_ack_in <= gpio2_ack_out; |
p_dat_in <= gpio2_dat_out; |
when MODULE_UART => |
p_ack_in <= uart_ack_out; |
p_dat_in <= (31 downto 8 => '0') & uart_dat_out; |
when MODULE_TIMER => |
p_ack_in <= timer_ack_out; |
p_dat_in <= timer_dat_out; |
when MODULE_DUMMY => |
p_ack_in <= dummy_ack_out; |
p_dat_in <= dummy_dat_out; |
when MODULE_NONE => |
p_ack_in <= '0'; |
p_dat_in <= (others => '0'); |
end case; |
end process module_mux; |
|
end architecture behaviour; |
/example/README
0,0 → 1,33
# Demo design for the Nexys 4 board |
|
This folder contains a design for a simple demo design using the Potato |
processor. It has been tested using Vivado 2014.4. |
|
## Quick Start |
|
In order to use the design, first import all source files from the folders |
`src/`, `soc/` and `example/` into your project. |
|
### Clocking |
|
Then add a clock generator using the Clocking Wizard. To seamlessly integrate |
it into the design, name it "clock_generator". Choose the following options: |
|
* Frequency Synthesis |
* Safe Clock Startup |
|
Set up two output clocks, `clk_out1` with frequency 50 MHz, and `clk_out2` with |
a frequency of 10 MHz. Rename the corresponding ports to `system_clk` and |
`timer_clk` respectively. Name the input clock `clk`. |
|
### Instruction memory |
|
Add a block RAM to use as instruction ROM using the Block Memory Generator. |
Choose "Single Port ROM" as memory type, set port A width to 32 bits and |
port A depth to 2048. Initialize it with your application binary and, |
optionally, fill the remaining memory locations with 0x00000013. |
|
### Test it! |
|
Now you can test it and hopefully it works :-) |
|
/example/nexys4_constraints.xdc
0,0 → 1,94
# Practical Test Application for the Potato Processor |
# (c) Kristian Klomsten Skordal 2015 <kristian.skordal@wafflemail.net> |
# Report bugs and issues on <https://github.com/skordal/potato-test/issues> |
|
# Operating conditions: |
set_operating_conditions -airflow 0 |
set_operating_conditions -heatsink low |
|
# Clock: |
set_property PACKAGE_PIN E3 [get_ports clk] |
set_property IOSTANDARD LVCMOS33 [get_ports clk] |
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk] |
|
# Reset: |
set_property PACKAGE_PIN C12 [get_ports reset_n] |
set_property IOSTANDARD LVCMOS33 [get_ports reset_n] |
|
# External interrupt button: |
set_property PACKAGE_PIN E16 [get_ports external_interrupt] |
set_property IOSTANDARD LVCMOS33 [get_ports external_interrupt] |
|
# UART (to host) lines: |
set_property PACKAGE_PIN C4 [get_ports uart_rxd] |
set_property IOSTANDARD LVCMOS33 [get_ports uart_rxd] |
set_property PACKAGE_PIN D4 [get_ports uart_txd] |
set_property IOSTANDARD LVCMOS33 [get_ports uart_txd] |
|
# Switches: |
set_property PACKAGE_PIN U9 [get_ports {switches[0]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[0]}] |
set_property PACKAGE_PIN U8 [get_ports {switches[1]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[1]}] |
set_property PACKAGE_PIN R7 [get_ports {switches[2]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[2]}] |
set_property PACKAGE_PIN R6 [get_ports {switches[3]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[3]}] |
set_property PACKAGE_PIN R5 [get_ports {switches[4]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[4]}] |
set_property PACKAGE_PIN V7 [get_ports {switches[5]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[5]}] |
set_property PACKAGE_PIN V6 [get_ports {switches[6]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[6]}] |
set_property PACKAGE_PIN V5 [get_ports {switches[7]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[7]}] |
set_property PACKAGE_PIN U4 [get_ports {switches[8]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[8]}] |
set_property PACKAGE_PIN V2 [get_ports {switches[9]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[9]}] |
set_property PACKAGE_PIN U2 [get_ports {switches[10]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[10]}] |
set_property PACKAGE_PIN T3 [get_ports {switches[11]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[11]}] |
set_property PACKAGE_PIN T1 [get_ports {switches[12]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[12]}] |
set_property PACKAGE_PIN R3 [get_ports {switches[13]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[13]}] |
set_property PACKAGE_PIN P3 [get_ports {switches[14]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[14]}] |
set_property PACKAGE_PIN P4 [get_ports {switches[15]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {switches[15]}] |
|
# LEDs: |
set_property PACKAGE_PIN T8 [get_ports {leds[0]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[0]}] |
set_property PACKAGE_PIN V9 [get_ports {leds[1]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[1]}] |
set_property PACKAGE_PIN R8 [get_ports {leds[2]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[2]}] |
set_property PACKAGE_PIN T6 [get_ports {leds[3]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[3]}] |
set_property PACKAGE_PIN T5 [get_ports {leds[4]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[4]}] |
set_property PACKAGE_PIN T4 [get_ports {leds[5]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[5]}] |
set_property PACKAGE_PIN U7 [get_ports {leds[6]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[6]}] |
set_property PACKAGE_PIN U6 [get_ports {leds[7]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[7]}] |
set_property PACKAGE_PIN V4 [get_ports {leds[8]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[8]}] |
set_property PACKAGE_PIN U3 [get_ports {leds[9]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[9]}] |
set_property PACKAGE_PIN V1 [get_ports {leds[10]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[10]}] |
set_property PACKAGE_PIN R1 [get_ports {leds[11]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[11]}] |
set_property PACKAGE_PIN P5 [get_ports {leds[12]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[12]}] |
set_property PACKAGE_PIN U1 [get_ports {leds[13]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[13]}] |
set_property PACKAGE_PIN R2 [get_ports {leds[14]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[14]}] |
set_property PACKAGE_PIN P2 [get_ports {leds[15]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {leds[15]}] |