Disabled external gits
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
-- #############################################################################
|
||||
-- DE0_Nano_SoC_PrSoC_extn_board_top_level.vhd
|
||||
--
|
||||
-- BOARD : PrSoC extension board for DE0-Nano-SoC
|
||||
-- Author : Florian Depraz based on Sahand Kashani-Akhavan work
|
||||
-- Revision : 1.1
|
||||
-- Creation date : 06/02/2016
|
||||
--
|
||||
-- Syntax Rule : GROUP_NAME_N[bit]
|
||||
--
|
||||
-- GROUP : specify a particular interface (ex: SDR_)
|
||||
-- NAME : signal name (ex: CONFIG, D, ...)
|
||||
-- bit : signal index
|
||||
-- _N : to specify an active-low signal
|
||||
-- #############################################################################
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity DE0_Nano_SoC_PrSoC_extn_board_top_level is
|
||||
port(
|
||||
-------------------------------
|
||||
-- Comment ALL unused ports. --
|
||||
-------------------------------
|
||||
|
||||
-- CLOCK
|
||||
FPGA_CLK1_50 : in std_logic;
|
||||
-- FPGA_CLK2_50 : in std_logic;
|
||||
-- FPGA_CLK3_50 : in std_logic;
|
||||
|
||||
-- KEY on DE0 Nano SoC
|
||||
KEY_N : in std_logic_vector(1 downto 0);
|
||||
|
||||
-- LEDs on DE0 Nano SoC
|
||||
-- LED : out std_logic_vector(7 downto 0);
|
||||
|
||||
-- SWITCHES on DE0 Nano SoC
|
||||
-- SW : in std_logic_vector(3 downto 0);
|
||||
|
||||
-- Servomotors pwm
|
||||
SERVO_0 : out std_logic;
|
||||
SERVO_1 : out std_logic;
|
||||
|
||||
-- ADC Joysticks
|
||||
J0_SPI_CS_n : out std_logic;
|
||||
J0_SPI_MOSI : out std_logic;
|
||||
J0_SPI_MISO : in std_logic;
|
||||
J0_SPI_CLK : out std_logic
|
||||
|
||||
-- Lepton
|
||||
-- CAM_TH_SPI_CS_N : out std_logic;
|
||||
-- CAM_TH_MISO : in std_logic;
|
||||
-- CAM_TH_MOSI : out std_logic;
|
||||
-- CAM_TH_CLK : out std_logic;
|
||||
|
||||
-- PCA9637
|
||||
-- PIO_SCL : inout std_logic;
|
||||
-- PIO_SDA : inout std_logic;
|
||||
-- PIO_INT_N : in std_logic;
|
||||
-- RESET_N : out std_logic;
|
||||
|
||||
-- OV7670
|
||||
-- CAM_D : in std_logic_vector(9 downto 0);
|
||||
-- CAM_PIX_CLK : in std_logic;
|
||||
-- CAM_LV : in std_logic;
|
||||
-- CAM_FV : in std_logic;
|
||||
-- CAM_SYS_CLK : out std_logic;
|
||||
|
||||
-- VGA and LCD shared signals
|
||||
-- VIDEO_CLK : out std_logic;
|
||||
-- VIDEO_VSYNC : out std_logic;
|
||||
-- VIDEO_HSYNC : out std_logic;
|
||||
-- VIDEO_B : out std_logic_vector(7 downto 0);
|
||||
-- VIDEO_G : out std_logic_vector(7 downto 0);
|
||||
-- VIDEO_R : out std_logic_vector(7 downto 0);
|
||||
|
||||
-- LCD Specific signals
|
||||
-- LCD_DE : out std_logic;
|
||||
-- LCD_PIN_DAV_N : ? ?? std_logic;
|
||||
-- LCD_DISPLAY_EN : out std_logic;
|
||||
-- SPI_MISO : in std_logic;
|
||||
-- SPI_ENA_N : out std_logic;
|
||||
-- SPI_CLK : out std_logic;
|
||||
-- SPI_MOSI : out std_logic;
|
||||
-- SPI_DAT : inout std_logic;
|
||||
|
||||
-- I2C TOUCH SCREEN
|
||||
-- TS_SCL : inout std_logic;
|
||||
-- TS_SDA : inout std_logic;
|
||||
|
||||
-- BLUETOOTH (BLE)
|
||||
-- BLT_TXD : in std_logic;
|
||||
-- BLT_RXD : out std_logic;
|
||||
|
||||
-- I2C For VGA, PAL and OV7670 cameras
|
||||
-- CAM_PAL_VGA_SDA : inout std_logic;
|
||||
-- CAM_PAL_VGA_SCL : inout std_logic;
|
||||
|
||||
-- ONE WIRE
|
||||
-- BOARD_ID : inout std_logic;
|
||||
|
||||
-- PAL Camera
|
||||
-- PAL_VD_VD : in std_logic_vector(7 downto 0);
|
||||
-- PAL_VD_VSO : in std_logic;
|
||||
-- PAL_VD_HSO : in std_logic;
|
||||
-- PAL_VD_CLKO : in std_logic;
|
||||
-- PAL_PWDN : out std_logic;
|
||||
|
||||
-- WIFI
|
||||
-- FROM_ESP_TXD : in std_logic;
|
||||
-- TO_ESP_RXD : out std_logic;
|
||||
|
||||
-- LED RGB
|
||||
-- LED_BGR : out std_logic;
|
||||
|
||||
-- HPS
|
||||
-- HPS_CONV_USB_N : inout std_logic;
|
||||
-- HPS_DDR3_ADDR : out std_logic_vector(14 downto 0);
|
||||
-- HPS_DDR3_BA : out std_logic_vector(2 downto 0);
|
||||
-- HPS_DDR3_CAS_N : out std_logic;
|
||||
-- HPS_DDR3_CK_N : out std_logic;
|
||||
-- HPS_DDR3_CK_P : out std_logic;
|
||||
-- HPS_DDR3_CKE : out std_logic;
|
||||
-- HPS_DDR3_CS_N : out std_logic;
|
||||
-- HPS_DDR3_DM : out std_logic_vector(3 downto 0);
|
||||
-- HPS_DDR3_DQ : inout std_logic_vector(31 downto 0);
|
||||
-- HPS_DDR3_DQS_N : inout std_logic_vector(3 downto 0);
|
||||
-- HPS_DDR3_DQS_P : inout std_logic_vector(3 downto 0);
|
||||
-- HPS_DDR3_ODT : out std_logic;
|
||||
-- HPS_DDR3_RAS_N : out std_logic;
|
||||
-- HPS_DDR3_RESET_N : out std_logic;
|
||||
-- HPS_DDR3_RZQ : in std_logic;
|
||||
-- HPS_DDR3_WE_N : out std_logic;
|
||||
-- HPS_ENET_GTX_CLK : out std_logic;
|
||||
-- HPS_ENET_INT_N : inout std_logic;
|
||||
-- HPS_ENET_MDC : out std_logic;
|
||||
-- HPS_ENET_MDIO : inout std_logic;
|
||||
-- HPS_ENET_RX_CLK : in std_logic;
|
||||
-- HPS_ENET_RX_DATA : in std_logic_vector(3 downto 0);
|
||||
-- HPS_ENET_RX_DV : in std_logic;
|
||||
-- HPS_ENET_TX_DATA : out std_logic_vector(3 downto 0);
|
||||
-- HPS_ENET_TX_EN : out std_logic;
|
||||
-- HPS_GSENSOR_INT : inout std_logic;
|
||||
-- HPS_I2C0_SCLK : inout std_logic;
|
||||
-- HPS_I2C0_SDAT : inout std_logic;
|
||||
-- HPS_I2C1_SCLK : inout std_logic;
|
||||
-- HPS_I2C1_SDAT : inout std_logic;
|
||||
-- HPS_KEY_N : inout std_logic;
|
||||
-- HPS_LED : inout std_logic;
|
||||
-- HPS_LTC_GPIO : inout std_logic;
|
||||
-- HPS_SD_CLK : out std_logic;
|
||||
-- HPS_SD_CMD : inout std_logic;
|
||||
-- HPS_SD_DATA : inout std_logic_vector(3 downto 0);
|
||||
-- HPS_SPIM_CLK : out std_logic;
|
||||
-- HPS_SPIM_MISO : in std_logic;
|
||||
-- HPS_SPIM_MOSI : out std_logic;
|
||||
-- HPS_SPIM_SS : inout std_logic;
|
||||
-- HPS_UART_RX : in std_logic;
|
||||
-- HPS_UART_TX : out std_logic;
|
||||
-- HPS_USB_CLKOUT : in std_logic;
|
||||
-- HPS_USB_DATA : inout std_logic_vector(7 downto 0);
|
||||
-- HPS_USB_DIR : in std_logic;
|
||||
-- HPS_USB_NXT : in std_logic;
|
||||
-- HPS_USB_STP : out std_logic
|
||||
);
|
||||
end entity DE0_Nano_SoC_PrSoC_extn_board_top_level;
|
||||
|
||||
architecture rtl of DE0_Nano_SoC_PrSoC_extn_board_top_level is
|
||||
component soc_system is
|
||||
port (
|
||||
clk_clk : in std_logic := 'X';
|
||||
reset_reset_n : in std_logic := 'X';
|
||||
pwm_0_conduit_end_pwm : out std_logic;
|
||||
pwm_1_conduit_end_pwm : out std_logic;
|
||||
mcp3204_0_conduit_end_cs_n : out std_logic;
|
||||
mcp3204_0_conduit_end_mosi : out std_logic;
|
||||
mcp3204_0_conduit_end_miso : in std_logic := 'X';
|
||||
mcp3204_0_conduit_end_sclk : out std_logic
|
||||
);
|
||||
end component soc_system;
|
||||
|
||||
begin
|
||||
soc_system_inst : component soc_system
|
||||
port map (
|
||||
clk_clk => FPGA_CLK1_50,
|
||||
reset_reset_n => KEY_N(0),
|
||||
pwm_0_conduit_end_pwm => SERVO_0,
|
||||
pwm_1_conduit_end_pwm => SERVO_1,
|
||||
mcp3204_0_conduit_end_cs_n => J0_SPI_CS_n,
|
||||
mcp3204_0_conduit_end_mosi => J0_SPI_MOSI,
|
||||
mcp3204_0_conduit_end_miso => J0_SPI_MISO,
|
||||
mcp3204_0_conduit_end_sclk => J0_SPI_CLK
|
||||
);
|
||||
|
||||
end;
|
138
cs309-psoc/lab_1_2/hw/hdl/joysticks/hdl/mcp3204.vhd
Normal file
138
cs309-psoc/lab_1_2/hw/hdl/joysticks/hdl/mcp3204.vhd
Normal file
@@ -0,0 +1,138 @@
|
||||
-- #############################################################################
|
||||
-- mcp3204.vhd
|
||||
-- ===========
|
||||
-- MCP3204 Avalon-MM slave interface.
|
||||
--
|
||||
-- Register map
|
||||
-- +-------+-----------+--------+------------------------------------+
|
||||
-- | RegNo | Name | Access | Description |
|
||||
-- +-------+-----------+--------+------------------------------------+
|
||||
-- | 0 | CHANNEL_0 | RO | 12-bit digital value of channel 0. |
|
||||
-- +-------+-----------+--------+------------------------------------+
|
||||
-- | 1 | CHANNEL_1 | RO | 12-bit digital value of channel 1. |
|
||||
-- +-------+-----------+--------+------------------------------------+
|
||||
-- | 2 | CHANNEL_2 | RO | 12-bit digital value of channel 2. |
|
||||
-- +-------+-----------+--------+------------------------------------+
|
||||
-- | 3 | CHANNEL_3 | RO | 12-bit digital value of channel 3. |
|
||||
-- +-------+-----------+--------+------------------------------------+
|
||||
--
|
||||
-- Author : Philémon Favrod [philemon.favrod@epfl.ch]
|
||||
-- Author : Sahand Kashani-Akhavan [sahand.kashani-akhavan@epfl.ch]
|
||||
-- Revision : 2
|
||||
-- Last modified : 2018-03-06
|
||||
-- #############################################################################
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
entity mcp3204 is
|
||||
port(
|
||||
-- Avalon Clock interface
|
||||
clk : in std_logic;
|
||||
|
||||
-- Avalon Reset interface
|
||||
reset : in std_logic;
|
||||
|
||||
-- Avalon-MM Slave interface
|
||||
address : in std_logic_vector(1 downto 0);
|
||||
read : in std_logic;
|
||||
readdata : out std_logic_vector(31 downto 0);
|
||||
|
||||
-- Avalon Conduit interface
|
||||
CS_N : out std_logic;
|
||||
MOSI : out std_logic;
|
||||
MISO : in std_logic;
|
||||
SCLK : out std_logic
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of mcp3204 is
|
||||
constant NUM_CHANNELS : positive := 4;
|
||||
constant CHANNEL_WIDTH : positive := integer(ceil(log2(real(NUM_CHANNELS))));
|
||||
|
||||
type data_array is array (NUM_CHANNELS - 1 downto 0) of std_logic_vector(readdata'range);
|
||||
signal data_reg : data_array;
|
||||
|
||||
signal spi_busy, spi_start, spi_datavalid : std_logic;
|
||||
signal spi_channel : std_logic_vector(1 downto 0);
|
||||
signal spi_data : std_logic_vector(11 downto 0);
|
||||
|
||||
type state_t is (READY, INIT_READ_CHANNEL, WAIT_FOR_DATA);
|
||||
signal state : state_t;
|
||||
|
||||
signal channel : unsigned(CHANNEL_WIDTH - 1 downto 0);
|
||||
|
||||
begin
|
||||
SPI : entity work.mcp3204_spi
|
||||
port map(
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
busy => spi_busy,
|
||||
start => spi_start,
|
||||
channel => spi_channel,
|
||||
data_valid => spi_datavalid,
|
||||
data => spi_data,
|
||||
SCLK => SCLK,
|
||||
CS_N => CS_N,
|
||||
MOSI => MOSI,
|
||||
MISO => MISO
|
||||
);
|
||||
|
||||
-- FSM that dictates which channel is being read. The state of the component
|
||||
-- should be thought as the pair (state, channel)
|
||||
p_fsm : process(reset, clk)
|
||||
begin
|
||||
if reset = '1' then
|
||||
state <= READY;
|
||||
channel <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
case state is
|
||||
when READY =>
|
||||
if spi_busy = '0' then
|
||||
state <= INIT_READ_CHANNEL;
|
||||
end if;
|
||||
|
||||
when INIT_READ_CHANNEL =>
|
||||
state <= WAIT_FOR_DATA;
|
||||
|
||||
when WAIT_FOR_DATA =>
|
||||
if spi_datavalid = '1' then
|
||||
state <= READY;
|
||||
channel <= channel + 1;
|
||||
end if;
|
||||
end case;
|
||||
end if;
|
||||
end process p_fsm;
|
||||
|
||||
-- Updates the internal registers when a new data is available
|
||||
p_data : process(reset, clk)
|
||||
begin
|
||||
if reset = '1' then
|
||||
for i in 0 to NUM_CHANNELS - 1 loop
|
||||
data_reg(i) <= (others => '0');
|
||||
end loop;
|
||||
elsif rising_edge(clk) then
|
||||
if state = WAIT_FOR_DATA and spi_datavalid = '1' then
|
||||
data_reg(to_integer(channel)) <= (31 downto 12 => '0') & spi_data;
|
||||
end if;
|
||||
end if;
|
||||
end process p_data;
|
||||
|
||||
spi_start <= '1' when state = INIT_READ_CHANNEL else '0';
|
||||
spi_channel <= std_logic_vector(channel);
|
||||
|
||||
-- Interface with the Avalon Switch Fabric
|
||||
p_avalon_read : process(reset, clk)
|
||||
begin
|
||||
if reset = '1' then
|
||||
readdata <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
if read = '1' then
|
||||
readdata <= data_reg(to_integer(unsigned(address)));
|
||||
end if;
|
||||
end if;
|
||||
end process p_avalon_read;
|
||||
|
||||
end architecture;
|
137
cs309-psoc/lab_1_2/hw/hdl/joysticks/hdl/mcp3204_hw.tcl
Normal file
137
cs309-psoc/lab_1_2/hw/hdl/joysticks/hdl/mcp3204_hw.tcl
Normal file
@@ -0,0 +1,137 @@
|
||||
# TCL File Generated by Component Editor 16.0
|
||||
# Sun Feb 05 18:14:06 CET 2017
|
||||
# DO NOT MODIFY
|
||||
|
||||
|
||||
#
|
||||
# mcp3204 "mcp3204" v1.0
|
||||
# Philemon Favrod & Sahand Kashani-Akhavan 2017.02.05.18:14:06
|
||||
# 4-Channel 12-Bit A/D Converter with SPI Serial Interface
|
||||
#
|
||||
|
||||
#
|
||||
# request TCL package from ACDS 16.0
|
||||
#
|
||||
package require -exact qsys 16.0
|
||||
|
||||
|
||||
#
|
||||
# module mcp3204
|
||||
#
|
||||
set_module_property DESCRIPTION "4-Channel 12-Bit A/D Converter with SPI Serial Interface"
|
||||
set_module_property NAME mcp3204
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property INTERNAL false
|
||||
set_module_property OPAQUE_ADDRESS_MAP true
|
||||
set_module_property GROUP Joystick
|
||||
set_module_property AUTHOR "Philemon Favrod & Sahand Kashani-Akhavan"
|
||||
set_module_property DISPLAY_NAME mcp3204
|
||||
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
|
||||
set_module_property EDITABLE true
|
||||
set_module_property REPORT_TO_TALKBACK false
|
||||
set_module_property ALLOW_GREYBOX_GENERATION false
|
||||
set_module_property REPORT_HIERARCHY false
|
||||
|
||||
|
||||
#
|
||||
# file sets
|
||||
#
|
||||
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
|
||||
set_fileset_property QUARTUS_SYNTH TOP_LEVEL mcp3204
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
|
||||
add_fileset_file mcp3204.vhd VHDL PATH mcp3204.vhd TOP_LEVEL_FILE
|
||||
add_fileset_file mcp3204_spi.vhd VHDL PATH mcp3204_spi.vhd
|
||||
|
||||
|
||||
#
|
||||
# parameters
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# display items
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# connection point clock
|
||||
#
|
||||
add_interface clock clock end
|
||||
set_interface_property clock clockRate 0
|
||||
set_interface_property clock ENABLED true
|
||||
set_interface_property clock EXPORT_OF ""
|
||||
set_interface_property clock PORT_NAME_MAP ""
|
||||
set_interface_property clock CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property clock SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port clock clk clk Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point reset
|
||||
#
|
||||
add_interface reset reset end
|
||||
set_interface_property reset associatedClock clock
|
||||
set_interface_property reset synchronousEdges DEASSERT
|
||||
set_interface_property reset ENABLED true
|
||||
set_interface_property reset EXPORT_OF ""
|
||||
set_interface_property reset PORT_NAME_MAP ""
|
||||
set_interface_property reset CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property reset SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port reset reset reset Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point avalon_slave_0
|
||||
#
|
||||
add_interface avalon_slave_0 avalon end
|
||||
set_interface_property avalon_slave_0 addressUnits WORDS
|
||||
set_interface_property avalon_slave_0 associatedClock clock
|
||||
set_interface_property avalon_slave_0 associatedReset reset
|
||||
set_interface_property avalon_slave_0 bitsPerSymbol 8
|
||||
set_interface_property avalon_slave_0 burstOnBurstBoundariesOnly false
|
||||
set_interface_property avalon_slave_0 burstcountUnits WORDS
|
||||
set_interface_property avalon_slave_0 explicitAddressSpan 0
|
||||
set_interface_property avalon_slave_0 holdTime 0
|
||||
set_interface_property avalon_slave_0 linewrapBursts false
|
||||
set_interface_property avalon_slave_0 maximumPendingReadTransactions 0
|
||||
set_interface_property avalon_slave_0 maximumPendingWriteTransactions 0
|
||||
set_interface_property avalon_slave_0 readLatency 0
|
||||
set_interface_property avalon_slave_0 readWaitTime 1
|
||||
set_interface_property avalon_slave_0 setupTime 0
|
||||
set_interface_property avalon_slave_0 timingUnits Cycles
|
||||
set_interface_property avalon_slave_0 writeWaitTime 0
|
||||
set_interface_property avalon_slave_0 ENABLED true
|
||||
set_interface_property avalon_slave_0 EXPORT_OF ""
|
||||
set_interface_property avalon_slave_0 PORT_NAME_MAP ""
|
||||
set_interface_property avalon_slave_0 CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property avalon_slave_0 SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port avalon_slave_0 address address Input 2
|
||||
add_interface_port avalon_slave_0 read read Input 1
|
||||
add_interface_port avalon_slave_0 readdata readdata Output 32
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isFlash 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isMemoryDevice 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isNonVolatileStorage 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isPrintableDevice 0
|
||||
|
||||
|
||||
#
|
||||
# connection point conduit_end
|
||||
#
|
||||
add_interface conduit_end conduit end
|
||||
set_interface_property conduit_end associatedClock clock
|
||||
set_interface_property conduit_end associatedReset ""
|
||||
set_interface_property conduit_end ENABLED true
|
||||
set_interface_property conduit_end EXPORT_OF ""
|
||||
set_interface_property conduit_end PORT_NAME_MAP ""
|
||||
set_interface_property conduit_end CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property conduit_end SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port conduit_end CS_N cs_n Output 1
|
||||
add_interface_port conduit_end MOSI mosi Output 1
|
||||
add_interface_port conduit_end MISO miso Input 1
|
||||
add_interface_port conduit_end SCLK sclk Output 1
|
||||
|
161
cs309-psoc/lab_1_2/hw/hdl/joysticks/hdl/mcp3204_spi.vhd
Normal file
161
cs309-psoc/lab_1_2/hw/hdl/joysticks/hdl/mcp3204_spi.vhd
Normal file
@@ -0,0 +1,161 @@
|
||||
-- #############################################################################
|
||||
-- mcp3204_spi.vhd
|
||||
-- ===============
|
||||
-- MCP3204 SPI interface.
|
||||
--
|
||||
-- Author : Philémon Favrod [philemon.favrod@epfl.ch]
|
||||
-- Author : Sahand Kashani-Akhavan [sahand.kashani-akhavan@epfl.ch]
|
||||
-- Author : <insert your name> (<insert your e-mail address>)
|
||||
-- Revision : 1
|
||||
-- Last modified : <insert date>
|
||||
-- #############################################################################
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity mcp3204_spi is
|
||||
port(
|
||||
-- 50 MHz
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
busy : out std_logic;
|
||||
start : in std_logic;
|
||||
channel : in std_logic_vector(1 downto 0);
|
||||
data_valid : out std_logic;
|
||||
data : out std_logic_vector(11 downto 0);
|
||||
|
||||
-- 1 MHz
|
||||
SCLK : out std_logic;
|
||||
CS_N : out std_logic;
|
||||
MOSI : out std_logic;
|
||||
MISO : in std_logic
|
||||
);
|
||||
end mcp3204_spi;
|
||||
|
||||
architecture rtl of mcp3204_spi is
|
||||
-- The signals that drive the clock divider
|
||||
signal reg_clk_divider_counter : unsigned(4 downto 0) := (others => '0'); -- need to be able to count until 24
|
||||
signal reg_spi_en : std_logic := '0'; -- pulses every 0.5 MHz
|
||||
signal reg_rising_edge_sclk : std_logic := '0';
|
||||
signal reg_falling_edge_sclk : std_logic := '0';
|
||||
signal reg_sclk : std_logic := '0';
|
||||
|
||||
-- The state related to the FSM
|
||||
type state_type is (IDL, SYN, SND_S, SND_SGL, SND_D, WT, RCV_NB, RCV_D, WB);
|
||||
signal reg_state, next_state : state_type := IDL;
|
||||
signal reg_bit_idx : unsigned(3 downto 0) := (others => '0');
|
||||
signal reg_channel : unsigned(1 downto 0);
|
||||
|
||||
-- The register that holds the transmitted data
|
||||
signal reg_data : unsigned(11 downto 0) := (others => '0');
|
||||
|
||||
begin
|
||||
clk_divider_generation : process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
reg_clk_divider_counter <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
reg_clk_divider_counter <= reg_clk_divider_counter + 1;
|
||||
reg_spi_en <= '0';
|
||||
reg_rising_edge_sclk <= '0';
|
||||
reg_falling_edge_sclk <= '0';
|
||||
|
||||
if reg_clk_divider_counter = 24 then
|
||||
reg_clk_divider_counter <= (others => '0');
|
||||
reg_spi_en <= '1';
|
||||
|
||||
if reg_sclk = '0' then
|
||||
reg_rising_edge_sclk <= '1';
|
||||
elsif reg_sclk = '1' then
|
||||
reg_falling_edge_sclk <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
SCLK_generation : process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
reg_sclk <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
if reg_spi_en = '1' then
|
||||
reg_sclk <= not reg_sclk;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
STATE_LOGIC : process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
reg_state <= IDL;
|
||||
reg_bit_idx <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
reg_state <= next_state;
|
||||
|
||||
case reg_state is
|
||||
when IDL =>
|
||||
if next_state = SYN then
|
||||
reg_channel <= unsigned(channel);
|
||||
end if;
|
||||
when SND_SGL =>
|
||||
if next_state = SND_D then
|
||||
reg_bit_idx <= to_unsigned(2, reg_bit_idx'length);
|
||||
end if;
|
||||
when RCV_NB =>
|
||||
if next_state = RCV_D then
|
||||
reg_bit_idx <= to_unsigned(11, reg_bit_idx'length);
|
||||
end if;
|
||||
when SND_D | RCV_D =>
|
||||
if reg_falling_edge_sclk = '1' then
|
||||
reg_bit_idx <= reg_bit_idx - 1;
|
||||
end if;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- This is the combinatory logic to compute the next state
|
||||
next_state <=
|
||||
SYN when reg_state = IDL and start = '1' else
|
||||
SND_S when reg_state = SYN and reg_falling_edge_sclk = '1' else
|
||||
SND_SGL when reg_state = SND_S and reg_falling_edge_sclk = '1' else
|
||||
SND_D when reg_state = SND_SGL and reg_falling_edge_sclk = '1' else
|
||||
WT when reg_state = SND_D and reg_falling_edge_sclk = '1' and reg_bit_idx = 0 else
|
||||
RCV_NB when reg_state = WT and reg_falling_edge_sclk = '1' else
|
||||
RCV_D when reg_state = RCV_NB and reg_falling_edge_sclk = '1' else
|
||||
WB when reg_state = RCV_D and reg_falling_edge_sclk = '1' and reg_bit_idx = 0 else
|
||||
IDL when reg_state = WB else
|
||||
reg_state;
|
||||
|
||||
-- This process reads the bits sent from the ADC
|
||||
ADC_READ : process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
reg_data <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
if reg_state = RCV_D and reg_rising_edge_sclk = '1' then
|
||||
reg_data(to_integer(reg_bit_idx)) <= MISO;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- This is the combinatory logic to the ADC converter
|
||||
SCLK <= reg_sclk;
|
||||
CS_N <= '1' when reg_state = IDL or reg_state = SYN or reg_state = WB else '0';
|
||||
MOSI <=
|
||||
'1' when reg_state = SND_S or reg_state = SND_SGL else
|
||||
'0' when reg_state = SND_D and reg_bit_idx = 2 else
|
||||
reg_channel(to_integer(reg_bit_idx)) when reg_state = SND_D else
|
||||
'0';
|
||||
|
||||
-- This is the combinatory logic to the SPI manager
|
||||
busy <= '0' when reg_state = IDL else
|
||||
'1';
|
||||
data_valid <= '1' when reg_state = WB else
|
||||
'0';
|
||||
data <= std_logic_vector(reg_data) when reg_state = WB else
|
||||
(others => '0');
|
||||
|
||||
end architecture rtl;
|
103
cs309-psoc/lab_1_2/hw/hdl/joysticks/tb/tb_mcp3204_spi.vhd
Normal file
103
cs309-psoc/lab_1_2/hw/hdl/joysticks/tb/tb_mcp3204_spi.vhd
Normal file
@@ -0,0 +1,103 @@
|
||||
-- #############################################################################
|
||||
-- tb_mcp3204_spi.vhd
|
||||
-- ==================
|
||||
-- Testbench for MCP3204 SPI interface.
|
||||
--
|
||||
-- Author : Sahand Kashani-Akhavan [sahand.kashani-akhavan@epfl.ch]
|
||||
-- Revision : 1
|
||||
-- Last modified : 2018-03-06
|
||||
-- #############################################################################
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity tb_mcp3204_spi is
|
||||
end entity;
|
||||
|
||||
architecture rtl of tb_mcp3204_spi is
|
||||
constant CLK_PERIOD : time := 20 ns;
|
||||
signal clk : std_logic := '0';
|
||||
signal reset : std_logic := '0';
|
||||
signal sim_finished : boolean := false;
|
||||
|
||||
-- mcp3204_spi ------------------------------------------------------------
|
||||
signal busy : std_logic := '0';
|
||||
signal start : std_logic := '0';
|
||||
signal channel : std_logic_vector(1 downto 0) := (others => '0');
|
||||
signal data_valid : std_logic := '0';
|
||||
signal data : std_logic_vector(11 downto 0) := (others => '0');
|
||||
signal SCLK : std_logic := '0';
|
||||
signal CS_N : std_logic := '1';
|
||||
signal MOSI : std_logic := '0';
|
||||
signal MISO : std_logic := '0';
|
||||
|
||||
begin
|
||||
duv : entity work.mcp3204_spi
|
||||
port map(
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
busy => busy,
|
||||
start => start,
|
||||
channel => channel,
|
||||
data_valid => data_valid,
|
||||
data => data,
|
||||
SCLK => SCLK,
|
||||
CS_N => CS_N,
|
||||
MOSI => MOSI,
|
||||
MISO => MISO
|
||||
);
|
||||
|
||||
clk <= not clk after CLK_PERIOD / 2 when not sim_finished;
|
||||
|
||||
sim : process
|
||||
procedure async_reset is
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
wait for CLK_PERIOD / 4;
|
||||
reset <= '1';
|
||||
|
||||
wait for CLK_PERIOD / 2;
|
||||
reset <= '0';
|
||||
end procedure async_reset;
|
||||
|
||||
procedure spi_transfer(constant channel_number : natural range 0 to 3) is
|
||||
begin
|
||||
if busy = '1' then
|
||||
wait until busy = '0';
|
||||
|
||||
else
|
||||
wait until falling_edge(clk);
|
||||
start <= '1';
|
||||
channel <= std_logic_vector(to_unsigned(channel_number, channel'length));
|
||||
|
||||
wait until falling_edge(clk);
|
||||
start <= '0';
|
||||
channel <= (others => '0');
|
||||
|
||||
wait until rising_edge(data_valid);
|
||||
wait until falling_edge(busy);
|
||||
end if;
|
||||
end procedure spi_transfer;
|
||||
|
||||
begin
|
||||
async_reset;
|
||||
|
||||
MISO <= '1';
|
||||
spi_transfer(0);
|
||||
|
||||
MISO <= '0';
|
||||
spi_transfer(1);
|
||||
|
||||
MISO <= '1';
|
||||
spi_transfer(2);
|
||||
|
||||
MISO <= '0';
|
||||
spi_transfer(3);
|
||||
|
||||
sim_finished <= true;
|
||||
wait;
|
||||
end process sim;
|
||||
end architecture rtl;
|
||||
|
||||
|
134
cs309-psoc/lab_1_2/hw/hdl/pantilt/hdl/pwm.vhd
Normal file
134
cs309-psoc/lab_1_2/hw/hdl/pantilt/hdl/pwm.vhd
Normal file
@@ -0,0 +1,134 @@
|
||||
-- #############################################################################
|
||||
-- pwm.vhd
|
||||
-- =======
|
||||
-- PWM memory-mapped Avalon slave interface.
|
||||
--
|
||||
-- Author : Cedric Hoelzl (cedric.hoelzl@epfl.ch)
|
||||
-- Author : Antoine Brunner (antoine.brunner@epfl.ch)
|
||||
-- Revision : 0.0.1a_rc1
|
||||
-- Last modified : a few billion clock cycles in the past
|
||||
-- #############################################################################
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
use work.pwm_constants.all;
|
||||
|
||||
entity pwm is
|
||||
port(
|
||||
-- Avalon Clock interface
|
||||
clk : in std_logic;
|
||||
|
||||
-- Avalon Reset interface
|
||||
reset : in std_logic;
|
||||
|
||||
-- Avalon-MM Slave interface
|
||||
address : in std_logic_vector(1 downto 0);
|
||||
read : in std_logic;
|
||||
write : in std_logic;
|
||||
readdata : out std_logic_vector(31 downto 0);
|
||||
writedata : in std_logic_vector(31 downto 0);
|
||||
|
||||
-- Avalon Conduit interface
|
||||
pwm_out : out std_logic
|
||||
);
|
||||
end pwm;
|
||||
|
||||
architecture rtl of pwm is
|
||||
|
||||
-- The period of the current and next PWM cycle
|
||||
signal reg_next_period : unsigned(writedata'range) := to_unsigned(DEFAULT_PERIOD, writedata'length);
|
||||
signal reg_current_period : unsigned(writedata'range) := to_unsigned(DEFAULT_PERIOD, writedata'length);
|
||||
|
||||
-- The duty cycle of the current and next PWM cycle
|
||||
signal reg_next_dutycycle : unsigned(writedata'range) := to_unsigned(DEFAULT_DUTY_CYCLE, writedata'length);
|
||||
signal reg_current_dutycycle : unsigned(writedata'range) := to_unsigned(DEFAULT_DUTY_CYCLE, writedata'length);
|
||||
|
||||
-- The status of the current and next PWM cycle
|
||||
signal reg_prev_ctrl : std_logic := '0';
|
||||
signal reg_current_ctrl : std_logic := '0';
|
||||
|
||||
-- The internal counter of the PWN
|
||||
signal reg_counter : unsigned(writedata'range) := to_unsigned(0, writedata'length);
|
||||
|
||||
begin
|
||||
|
||||
--Avalon-MM slave write
|
||||
process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
reg_next_period <= to_unsigned(DEFAULT_PERIOD, writedata'length);
|
||||
reg_next_dutycycle <= to_unsigned(DEFAULT_DUTY_CYCLE, writedata'length);
|
||||
reg_current_ctrl <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
if write = '1' then
|
||||
case address is
|
||||
when REG_PERIOD_OFST =>
|
||||
if unsigned(writedata) >= to_unsigned(2, writedata'length) then
|
||||
reg_next_period <= unsigned(writedata);
|
||||
end if;
|
||||
when REG_DUTY_CYCLE_OFST =>
|
||||
if (unsigned(writedata) >= to_unsigned(1, writedata'length)) and
|
||||
(unsigned(writedata) <= reg_next_period) then
|
||||
reg_next_dutycycle <= unsigned(writedata);
|
||||
end if;
|
||||
when REG_CTRL_OFST =>
|
||||
reg_current_ctrl <= writedata(0);
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
--Avalon-MM slave read
|
||||
process(clk, reset)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if read = '1' then
|
||||
case address is
|
||||
when REG_PERIOD_OFST =>
|
||||
readdata <= std_logic_vector(reg_current_period);
|
||||
when REG_DUTY_CYCLE_OFST =>
|
||||
readdata <= std_logic_vector(reg_current_dutycycle);
|
||||
when others =>
|
||||
readdata <= (others => '0');
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Internal synchronous logic
|
||||
process(clk, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
reg_counter <= to_unsigned(0, writedata'length);
|
||||
reg_prev_ctrl <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
if ((reg_prev_ctrl = '0') and (reg_current_ctrl = '1')) or
|
||||
(reg_counter = reg_current_period - 1) then
|
||||
reg_current_period <= reg_next_period;
|
||||
reg_current_dutycycle <= reg_next_dutycycle;
|
||||
reg_counter <= to_unsigned(0, writedata'length);
|
||||
elsif (reg_current_ctrl = '1') then
|
||||
reg_counter <= reg_counter + 1;
|
||||
end if;
|
||||
reg_prev_ctrl <= reg_current_ctrl;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Avalon Conduit interface
|
||||
process(clk, reset)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
|
||||
if (reg_counter < reg_current_dutycycle) and (reg_current_ctrl = '1') then
|
||||
pwm_out <= '1';
|
||||
else
|
||||
pwm_out <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture rtl;
|
61
cs309-psoc/lab_1_2/hw/hdl/pantilt/hdl/pwm_constants.vhd
Normal file
61
cs309-psoc/lab_1_2/hw/hdl/pantilt/hdl/pwm_constants.vhd
Normal file
@@ -0,0 +1,61 @@
|
||||
-- #############################################################################
|
||||
-- pwm_constants.vhd
|
||||
-- =================
|
||||
-- This package contains constants used in the PWM design files.
|
||||
--
|
||||
-- Author : Sahand Kashani-Akhavan [sahand.kashani-akhavan@epfl.ch]
|
||||
-- Revision : 2
|
||||
-- Last modified : 2018-02-28
|
||||
-- #############################################################################
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
package pwm_constants is
|
||||
-- Register map
|
||||
-- +--------+------------+--------+------------------------------------------------------------------------------+
|
||||
-- | RegNo | Name | Access | Description |
|
||||
-- +--------+------------+--------+------------------------------------------------------------------------------+
|
||||
-- | 0 | PERIOD | R/W | Period in clock cycles [2 <= period <= (2**32) - 1]. |
|
||||
-- | | | | |
|
||||
-- | | | | This value can be read/written while the unit is in the middle of an ongoing |
|
||||
-- | | | | PWM pulse. To allow safe behaviour, one cannot modify the period of an |
|
||||
-- | | | | ongoing pulse, so we adopt the following semantics for this register: |
|
||||
-- | | | | |
|
||||
-- | | | | >> WRITING a value in this register indicates the NEW period to apply to the |
|
||||
-- | | | | next pulse. |
|
||||
-- | | | | |
|
||||
-- | | | | >> READING a value from this register indicates the CURRENT period of the |
|
||||
-- | | | | ongoing pulse. |
|
||||
-- +--------+------------+--------+------------------------------------------------------------------------------+
|
||||
-- | 1 | DUTY_CYCLE | R/W | Duty cycle of the PWM [1 <= duty cycle <= period] |
|
||||
-- | | | | |
|
||||
-- | | | | This value can be read/written while the unit is in the middle of an ongoing |
|
||||
-- | | | | PWM pulse. To allow safe behaviour, one cannot modify the duty cycle of an |
|
||||
-- | | | | ongoing pulse, so we adopt the following semantics for this register: |
|
||||
-- | | | | |
|
||||
-- | | | | >> WRITING a value in this register indicates the NEW duty cycle to apply to |
|
||||
-- | | | | the next pulse. |
|
||||
-- | | | | |
|
||||
-- | | | | >> READING a value from this register indicates the CURRENT duty cycle of |
|
||||
-- | | | | the ongoing pulse. |
|
||||
-- +--------+------------+--------+------------------------------------------------------------------------------+
|
||||
-- | 2 | CTRL | WO | >> Writing 0 to this register stops the PWM once the ongoing pulse has ended.|
|
||||
-- | | | | Writing 1 to this register starts the PWM. |
|
||||
-- | | | | |
|
||||
-- | | | | >> Reading this register always returns 0. |
|
||||
-- +--------+------------+--------+------------------------------------------------------------------------------+
|
||||
constant REG_PERIOD_OFST : std_logic_vector(1 downto 0) := "00";
|
||||
constant REG_DUTY_CYCLE_OFST : std_logic_vector(1 downto 0) := "01";
|
||||
constant REG_CTRL_OFST : std_logic_vector(1 downto 0) := "10";
|
||||
|
||||
-- Default values of registers after reset (BEFORE writing START to the CTRL
|
||||
-- register with a new configuration)
|
||||
constant DEFAULT_PERIOD : natural := 4;
|
||||
constant DEFAULT_DUTY_CYCLE : natural := 2;
|
||||
end package pwm_constants;
|
||||
|
||||
package body pwm_constants is
|
||||
|
||||
end package body pwm_constants;
|
135
cs309-psoc/lab_1_2/hw/hdl/pantilt/hdl/pwm_hw.tcl
Normal file
135
cs309-psoc/lab_1_2/hw/hdl/pantilt/hdl/pwm_hw.tcl
Normal file
@@ -0,0 +1,135 @@
|
||||
# TCL File Generated by Component Editor 16.0
|
||||
# Tue Feb 28 12:18:00 CET 2017
|
||||
# DO NOT MODIFY
|
||||
|
||||
|
||||
#
|
||||
# pwm "pwm" v1.0
|
||||
# 2017.02.28.12:18:00
|
||||
# Pan-tilt
|
||||
#
|
||||
|
||||
#
|
||||
# request TCL package from ACDS 16.0
|
||||
#
|
||||
package require -exact qsys 16.0
|
||||
|
||||
|
||||
#
|
||||
# module pwm
|
||||
#
|
||||
set_module_property DESCRIPTION Pan-tilt
|
||||
set_module_property NAME pwm
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property INTERNAL false
|
||||
set_module_property OPAQUE_ADDRESS_MAP true
|
||||
set_module_property GROUP Pan-tilt
|
||||
set_module_property AUTHOR ""
|
||||
set_module_property DISPLAY_NAME pwm
|
||||
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
|
||||
set_module_property EDITABLE true
|
||||
set_module_property REPORT_TO_TALKBACK false
|
||||
set_module_property ALLOW_GREYBOX_GENERATION false
|
||||
set_module_property REPORT_HIERARCHY false
|
||||
|
||||
|
||||
#
|
||||
# file sets
|
||||
#
|
||||
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
|
||||
set_fileset_property QUARTUS_SYNTH TOP_LEVEL pwm
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
|
||||
add_fileset_file pwm.vhd VHDL PATH pwm.vhd TOP_LEVEL_FILE
|
||||
add_fileset_file pwm_constants.vhd VHDL PATH pwm_constants.vhd
|
||||
|
||||
|
||||
#
|
||||
# parameters
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# display items
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# connection point clock
|
||||
#
|
||||
add_interface clock clock end
|
||||
set_interface_property clock clockRate 0
|
||||
set_interface_property clock ENABLED true
|
||||
set_interface_property clock EXPORT_OF ""
|
||||
set_interface_property clock PORT_NAME_MAP ""
|
||||
set_interface_property clock CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property clock SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port clock clk clk Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point reset
|
||||
#
|
||||
add_interface reset reset end
|
||||
set_interface_property reset associatedClock clock
|
||||
set_interface_property reset synchronousEdges DEASSERT
|
||||
set_interface_property reset ENABLED true
|
||||
set_interface_property reset EXPORT_OF ""
|
||||
set_interface_property reset PORT_NAME_MAP ""
|
||||
set_interface_property reset CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property reset SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port reset reset reset Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point avalon_slave_0
|
||||
#
|
||||
add_interface avalon_slave_0 avalon end
|
||||
set_interface_property avalon_slave_0 addressUnits WORDS
|
||||
set_interface_property avalon_slave_0 associatedClock clock
|
||||
set_interface_property avalon_slave_0 associatedReset reset
|
||||
set_interface_property avalon_slave_0 bitsPerSymbol 8
|
||||
set_interface_property avalon_slave_0 burstOnBurstBoundariesOnly false
|
||||
set_interface_property avalon_slave_0 burstcountUnits WORDS
|
||||
set_interface_property avalon_slave_0 explicitAddressSpan 0
|
||||
set_interface_property avalon_slave_0 holdTime 0
|
||||
set_interface_property avalon_slave_0 linewrapBursts false
|
||||
set_interface_property avalon_slave_0 maximumPendingReadTransactions 0
|
||||
set_interface_property avalon_slave_0 maximumPendingWriteTransactions 0
|
||||
set_interface_property avalon_slave_0 readLatency 0
|
||||
set_interface_property avalon_slave_0 readWaitTime 1
|
||||
set_interface_property avalon_slave_0 setupTime 0
|
||||
set_interface_property avalon_slave_0 timingUnits Cycles
|
||||
set_interface_property avalon_slave_0 writeWaitTime 0
|
||||
set_interface_property avalon_slave_0 ENABLED true
|
||||
set_interface_property avalon_slave_0 EXPORT_OF ""
|
||||
set_interface_property avalon_slave_0 PORT_NAME_MAP ""
|
||||
set_interface_property avalon_slave_0 CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property avalon_slave_0 SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port avalon_slave_0 address address Input 2
|
||||
add_interface_port avalon_slave_0 read read Input 1
|
||||
add_interface_port avalon_slave_0 write write Input 1
|
||||
add_interface_port avalon_slave_0 readdata readdata Output 32
|
||||
add_interface_port avalon_slave_0 writedata writedata Input 32
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isFlash 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isMemoryDevice 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isNonVolatileStorage 0
|
||||
set_interface_assignment avalon_slave_0 embeddedsw.configuration.isPrintableDevice 0
|
||||
|
||||
|
||||
#
|
||||
# connection point conduit_end
|
||||
#
|
||||
add_interface conduit_end conduit end
|
||||
set_interface_property conduit_end associatedClock clock
|
||||
set_interface_property conduit_end associatedReset ""
|
||||
set_interface_property conduit_end ENABLED true
|
||||
set_interface_property conduit_end EXPORT_OF ""
|
||||
set_interface_property conduit_end PORT_NAME_MAP ""
|
||||
set_interface_property conduit_end CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property conduit_end SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port conduit_end pwm_out pwm Output 1
|
205
cs309-psoc/lab_1_2/hw/hdl/pantilt/tb/tb_pwm.vhd
Normal file
205
cs309-psoc/lab_1_2/hw/hdl/pantilt/tb/tb_pwm.vhd
Normal file
@@ -0,0 +1,205 @@
|
||||
-- #############################################################################
|
||||
-- tb_pwm.vhd
|
||||
-- ==========
|
||||
-- Testbench for PWM memory-mapped Avalon slave interface.
|
||||
--
|
||||
-- Modified by : Sahand Kashani-Akhavan [sahand.kashani-akhavan@epfl.ch]
|
||||
-- Revision : 2
|
||||
-- Last modified : 2018-02-28
|
||||
-- #############################################################################
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
use work.pwm_constants.all;
|
||||
|
||||
entity tb_pwm is
|
||||
end entity;
|
||||
|
||||
architecture rtl of tb_pwm is
|
||||
|
||||
-- 50 MHz clock
|
||||
constant CLK_PERIOD : time := 20 ns;
|
||||
|
||||
-- Signal used to end simulator when we finished submitting our test cases
|
||||
signal sim_finished : boolean := false;
|
||||
|
||||
-- PWM PORTS
|
||||
signal clk : std_logic;
|
||||
signal reset : std_logic;
|
||||
signal address : std_logic_vector(1 downto 0);
|
||||
signal read : std_logic;
|
||||
signal write : std_logic;
|
||||
signal readdata : std_logic_vector(31 downto 0);
|
||||
signal writedata : std_logic_vector(31 downto 0);
|
||||
signal pwm_out : std_logic;
|
||||
|
||||
-- Values of registers we are going to use to configure the PWM unit
|
||||
constant CONFIG_PERIOD : natural := 100;
|
||||
constant CONFIG_DUTY_CYCLE : natural := 20;
|
||||
constant CONFIG_CTRL_START : natural := 1;
|
||||
constant CONFIG_CTRL_STOP : natural := 0;
|
||||
|
||||
begin
|
||||
|
||||
-- Instantiate DUT
|
||||
dut : entity work.pwm
|
||||
port map(
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
address => address,
|
||||
read => read,
|
||||
write => write,
|
||||
readdata => readdata,
|
||||
writedata => writedata,
|
||||
pwm_out => pwm_out
|
||||
);
|
||||
|
||||
-- Generate clk signal
|
||||
clk_generation : process
|
||||
begin
|
||||
if not sim_finished then
|
||||
clk <= '1';
|
||||
wait for CLK_PERIOD / 2;
|
||||
clk <= '0';
|
||||
wait for CLK_PERIOD / 2;
|
||||
else
|
||||
wait;
|
||||
end if;
|
||||
end process clk_generation;
|
||||
|
||||
-- Test PWM
|
||||
simulation : process
|
||||
|
||||
procedure async_reset is
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
wait for CLK_PERIOD / 4;
|
||||
|
||||
reset <= '1';
|
||||
wait for CLK_PERIOD / 2;
|
||||
|
||||
reset <= '0';
|
||||
wait for CLK_PERIOD / 4;
|
||||
end procedure async_reset;
|
||||
|
||||
procedure write_register(constant ofst : in std_logic_vector(1 downto 0);
|
||||
constant val : in natural) is
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
|
||||
address <= ofst;
|
||||
write <= '1';
|
||||
writedata <= std_logic_vector(to_unsigned(val, writedata'length));
|
||||
wait until rising_edge(clk);
|
||||
|
||||
address <= (others => '0');
|
||||
write <= '0';
|
||||
writedata <= (others => '0');
|
||||
wait until rising_edge(clk);
|
||||
end procedure write_register;
|
||||
|
||||
procedure read_register(constant ofst : in std_logic_vector(1 downto 0)) is
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
|
||||
address <= ofst;
|
||||
read <= '1';
|
||||
-- The read has a 1 cycle wait-state, so we need to keep the read
|
||||
-- signal high for 2 clock cycles.
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
|
||||
address <= (others => '0');
|
||||
read <= '0';
|
||||
wait until rising_edge(clk);
|
||||
end procedure read_register;
|
||||
|
||||
procedure read_register_check(constant ofst : in std_logic_vector(1 downto 0);
|
||||
constant expected_val : in natural) is
|
||||
begin
|
||||
read_register(ofst);
|
||||
|
||||
case ofst is
|
||||
when REG_PERIOD_OFST =>
|
||||
assert to_integer(unsigned(readdata)) = expected_val
|
||||
report "Unexpected PERIOD: " &
|
||||
"PERIOD = " & integer'image(to_integer(unsigned(readdata))) & "; " &
|
||||
"PERIOD_expected = " & integer'image(expected_val)
|
||||
severity error;
|
||||
|
||||
when REG_DUTY_CYCLE_OFST =>
|
||||
assert to_integer(unsigned(readdata)) = expected_val
|
||||
report "Unexpected DUTY_CYCLE: " &
|
||||
"DUTY_CYCLE = " & integer'image(to_integer(unsigned(readdata))) & "; " &
|
||||
"DUTY_CYCLE_expected = " & integer'image(expected_val)
|
||||
severity error;
|
||||
|
||||
when REG_CTRL_OFST =>
|
||||
assert to_integer(unsigned(readdata)) = expected_val
|
||||
report "Unexpected CTRL: " &
|
||||
"CTRL = " & integer'image(to_integer(unsigned(readdata))) & "; " &
|
||||
"CTRL_expected = " & integer'image(expected_val)
|
||||
severity error;
|
||||
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end procedure read_register_check;
|
||||
|
||||
begin
|
||||
|
||||
-- Default values
|
||||
reset <= '0';
|
||||
address <= (others => '0');
|
||||
read <= '0';
|
||||
write <= '0';
|
||||
writedata <= (others => '0');
|
||||
wait until rising_edge(clk);
|
||||
|
||||
-- Reset the circuit
|
||||
async_reset;
|
||||
|
||||
-- Write desired configuration to PWM Avalon-MM slave.
|
||||
write_register(REG_PERIOD_OFST, CONFIG_PERIOD);
|
||||
write_register(REG_DUTY_CYCLE_OFST, CONFIG_DUTY_CYCLE);
|
||||
|
||||
-- Read back configuration from PWM Avalon-MM slave. Note that we have
|
||||
-- not started the PWM unit yet, so the new configuration must not be
|
||||
-- read back at this point (as per the register map).
|
||||
read_register_check(REG_PERIOD_OFST, DEFAULT_PERIOD);
|
||||
read_register_check(REG_DUTY_CYCLE_OFST, DEFAULT_DUTY_CYCLE);
|
||||
read_register_check(REG_CTRL_OFST, 0);
|
||||
|
||||
-- Start PWM
|
||||
write_register(REG_CTRL_OFST, CONFIG_CTRL_START);
|
||||
|
||||
-- Wait until PWM pulses for the first time after we sent START.
|
||||
wait until rising_edge(pwm_out);
|
||||
|
||||
-- Read back configuration from PWM Avalon-MM slave. Now that we have
|
||||
-- started the PWM unit, we should be able to read back the
|
||||
-- configuration we wrote (as per the register map).
|
||||
read_register_check(REG_PERIOD_OFST, CONFIG_PERIOD);
|
||||
read_register_check(REG_DUTY_CYCLE_OFST, CONFIG_DUTY_CYCLE);
|
||||
read_register_check(REG_CTRL_OFST, 0);
|
||||
|
||||
-- Wait for 2 PWM periods to finish
|
||||
wait for 2 * CLK_PERIOD * CONFIG_PERIOD;
|
||||
|
||||
-- Stop PWM.
|
||||
write_register(REG_CTRL_OFST, CONFIG_CTRL_STOP);
|
||||
|
||||
-- Wait for PWM period to finish
|
||||
wait for 1 * CLK_PERIOD * CONFIG_PERIOD;
|
||||
|
||||
-- Instruct "clk_generation" process to halt execution.
|
||||
sim_finished <= true;
|
||||
|
||||
-- Make this process wait indefinitely (it will never re-execute from
|
||||
-- its beginning again).
|
||||
wait;
|
||||
end process simulation;
|
||||
end architecture rtl;
|
||||
|
Reference in New Issue
Block a user