Disabled external gits

This commit is contained in:
2022-04-07 18:54:11 +02:00
parent 15e7120d6d
commit 0fb3e365d4
376 changed files with 50840 additions and 0 deletions

View File

@@ -0,0 +1,139 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.utils.all;
entity avalon_st_spi_master is
generic(
INPUT_CLK_FREQ : integer := 50000000;
SPI_SCLK_FREQ : integer := 10000000;
CPOL : integer := 1;
CPHA : integer := 1
);
port(
-- Input clock
clk : in std_logic;
-- Reset
reset : in std_logic;
spi_cs_n : in std_logic;
-- Sink Avalon ST Interface
mosi_sink_data : in std_logic_vector(7 downto 0);
mosi_sink_valid : in std_logic;
mosi_sink_ready : out std_logic;
-- Source Avalon ST Interface
miso_src_data : out std_logic_vector(7 downto 0);
miso_src_valid : out std_logic;
-- SPI Master signals
SCLK : out std_logic;
MISO : in std_logic;
MOSI : out std_logic;
CS_n : out std_logic
);
end avalon_st_spi_master;
architecture rtl of avalon_st_spi_master is
constant SCLK_PRESCALER_MAX : integer := INPUT_CLK_FREQ / SPI_SCLK_FREQ / 2;
signal sclk_prescaler : unsigned(bitlength(SCLK_PRESCALER_MAX) downto 0);
signal sclk_toggle : std_logic;
signal new_sink_buffer, cur_sink_buffer : std_logic_vector(mosi_sink_data'range);
signal new_sink_buffer_busy, cur_sink_buffer_busy : std_logic;
signal miso_src_buffer : std_logic_vector(7 downto 0);
signal spi_done, i_sclk : std_logic;
signal spi_bit_index : unsigned(2 downto 0);
begin
CS_n <= spi_cs_n;
p_sclk_prescaler : process(clk, reset) is
begin
if reset = '1' then
sclk_prescaler <= to_unsigned(1, sclk_prescaler'length);
elsif rising_edge(clk) then
if sclk_prescaler = SCLK_PRESCALER_MAX then
sclk_prescaler <= to_unsigned(1, sclk_prescaler'length);
else
sclk_prescaler <= sclk_prescaler + 1;
end if;
end if;
end process p_sclk_prescaler;
sclk_toggle <= '1' when sclk_prescaler = SCLK_PRESCALER_MAX else '0';
p_avalon_st_sink : process(clk, reset) is
begin
if reset = '1' then
new_sink_buffer_busy <= '0';
new_sink_buffer <= (others => '0');
elsif rising_edge(clk) then
if mosi_sink_valid = '1' then
if new_sink_buffer_busy = '0' and cur_sink_buffer_busy = '1' then
new_sink_buffer <= mosi_sink_data;
new_sink_buffer_busy <= '1';
end if;
elsif new_sink_buffer_busy = '1' and cur_sink_buffer_busy = '0' then
new_sink_buffer_busy <= '0';
end if;
end if;
end process p_avalon_st_sink;
mosi_sink_ready <= not new_sink_buffer_busy;
p_cur_buffer : process(clk, reset) is
begin
if reset = '1' then
cur_sink_buffer <= (others => '0');
cur_sink_buffer_busy <= '0';
elsif rising_edge(clk) then
if mosi_sink_valid = '1' and cur_sink_buffer_busy = '0' then
cur_sink_buffer <= mosi_sink_data;
cur_sink_buffer_busy <= '1';
elsif cur_sink_buffer_busy = '0' and new_sink_buffer_busy = '1' then
cur_sink_buffer <= new_sink_buffer;
cur_sink_buffer_busy <= '1';
elsif cur_sink_buffer_busy = '1' and spi_done = '1' then
cur_sink_buffer_busy <= '0';
end if;
end if;
end process p_cur_buffer;
p_spi : process(clk, reset) is
begin
if reset = '1' then
spi_done <= '0';
i_sclk <= to_unsigned(CPOL, 1)(0);
spi_bit_index <= "000";
MOSI <= '0';
miso_src_data <= (others => '0');
miso_src_valid <= '0';
miso_src_buffer <= (others => '0');
elsif rising_edge(clk) then
spi_done <= '0';
miso_src_valid <= '0';
if cur_sink_buffer_busy = '1' and sclk_toggle = '1' then
if i_sclk /= to_unsigned(CPHA, 1)(0) then
if spi_bit_index = "111" then
spi_done <= '1';
spi_bit_index <= "000";
miso_src_valid <= '1';
miso_src_data <= miso_src_buffer(7 downto 1) & MISO;
else
MOSI <= cur_sink_buffer(7 - to_integer(spi_bit_index));
miso_src_buffer(7 - to_integer(spi_bit_index)) <= MISO;
spi_bit_index <= spi_bit_index + 1;
end if;
end if;
i_sclk <= not i_sclk;
end if;
end if;
end process p_spi;
SCLK <= i_sclk;
end rtl;

View File

@@ -0,0 +1,87 @@
-------------------------------------------------------------------------------
-- Title : Byte stream to pixel converter for the Lepton Camera
-- Project : PrSoC
-------------------------------------------------------------------------------
-- File : byte2pix.vhd
-- Author : Philemon Orphee Favrod <pofavrod@lappc5.epfl.ch>
-- Company :
-- Created : 2016-03-21
-- Last update: 2017-03-19
-- Platform :
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description: Converts a byte stream to a 14-bit pixel stream.
-------------------------------------------------------------------------------
-- Copyright (c) 2016
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2016-03-21 1.0 pofavrod Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity byte2pix is
port(
clk, reset : in std_logic;
byte_data : in std_logic_vector(7 downto 0);
byte_valid : in std_logic;
byte_sof : in std_logic;
byte_eof : in std_logic;
pix_data : out std_logic_vector(13 downto 0);
pix_valid : out std_logic;
pix_sof : out std_logic;
pix_eof : out std_logic);
end byte2pix;
architecture rtl of byte2pix is
signal last_sof : std_logic;
signal msb : std_logic_vector(5 downto 0);
signal cnt : std_logic; -- used to skip msb sampling every other time
begin
process(clk, reset)
begin
if reset = '1' then
msb <= (others => '0');
cnt <= '0';
last_sof <= '0';
elsif rising_edge(clk) then
if byte_valid = '1' then
if cnt = '0' then
msb <= byte_data(5 downto 0);
last_sof <= byte_sof;
end if;
cnt <= not cnt;
end if;
end if;
end process;
process(clk, reset)
begin
if reset = '1' then
pix_data <= (others => '0');
pix_valid <= '0';
pix_sof <= '0';
pix_eof <= '0';
elsif rising_edge(clk) then
pix_data <= (others => '0');
pix_valid <= '0';
pix_sof <= '0';
pix_eof <= '0';
if byte_valid = '1' then
if cnt = '1' then
pix_data <= msb & byte_data;
pix_valid <= '1';
pix_sof <= last_sof;
pix_eof <= byte_eof;
end if;
end if;
end if;
end process;
end architecture rtl;

View File

@@ -0,0 +1,192 @@
-- megafunction wizard: %RAM: 2-PORT%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altsyncram
-- ============================================================
-- File Name: dual_ported_ram.vhd
-- Megafunction Name(s):
-- altsyncram
--
-- Simulation Library Files(s):
-- altera_mf
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 15.1.0 Build 185 10/21/2015 SJ Lite Edition
-- ************************************************************
--Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
--Your use of Altera Corporation's design tools, logic functions
--and other software and tools, and its AMPP partner logic
--functions, and any output files from any of the foregoing
--(including device programming or simulation files), and any
--associated documentation or information are expressly subject
--to the terms and conditions of the Altera Program License
--Subscription Agreement, the Altera Quartus Prime License Agreement,
--the Altera MegaCore Function License Agreement, or other
--applicable license agreement, including, without limitation,
--that your use is for the sole purpose of programming logic
--devices manufactured by Altera and sold by Altera or its
--authorized distributors. Please refer to the applicable
--agreement for further details.
library ieee;
use ieee.std_logic_1164.all;
library altera_mf;
use altera_mf.altera_mf_components.all;
entity dual_ported_ram is
port(
clock : in std_logic := '1';
data : in std_logic_vector(15 downto 0);
rdaddress : in std_logic_vector(12 downto 0);
wraddress : in std_logic_vector(12 downto 0);
wren : in std_logic := '0';
q : out std_logic_vector(15 downto 0)
);
end dual_ported_ram;
architecture SYN of dual_ported_ram is
signal sub_wire0 : std_logic_vector(15 downto 0);
begin
q <= sub_wire0(15 downto 0);
altsyncram_component : altsyncram
generic map(
address_aclr_b => "NONE",
address_reg_b => "CLOCK0",
clock_enable_input_a => "BYPASS",
clock_enable_input_b => "BYPASS",
clock_enable_output_b => "BYPASS",
intended_device_family => "Cyclone V",
lpm_type => "altsyncram",
numwords_a => 8192,
numwords_b => 8192,
operation_mode => "DUAL_PORT",
outdata_aclr_b => "NONE",
outdata_reg_b => "CLOCK0",
power_up_uninitialized => "FALSE",
read_during_write_mode_mixed_ports => "DONT_CARE",
widthad_a => 13,
widthad_b => 13,
width_a => 16,
width_b => 16,
width_byteena_a => 1
)
port map(
address_a => wraddress,
address_b => rdaddress,
clock0 => clock,
data_a => data,
wren_a => wren,
q_b => sub_wire0
);
end SYN;
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
-- Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
-- Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
-- Retrieval info: PRIVATE: CLRdata NUMERIC "0"
-- Retrieval info: PRIVATE: CLRq NUMERIC "0"
-- Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
-- Retrieval info: PRIVATE: CLRrren NUMERIC "0"
-- Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
-- Retrieval info: PRIVATE: CLRwren NUMERIC "0"
-- Retrieval info: PRIVATE: Clock NUMERIC "0"
-- Retrieval info: PRIVATE: Clock_A NUMERIC "0"
-- Retrieval info: PRIVATE: Clock_B NUMERIC "0"
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
-- Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0"
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B"
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
-- Retrieval info: PRIVATE: MEMSIZE NUMERIC "131072"
-- Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
-- Retrieval info: PRIVATE: MIFfilename STRING ""
-- Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2"
-- Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "1"
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3"
-- Retrieval info: PRIVATE: REGdata NUMERIC "1"
-- Retrieval info: PRIVATE: REGq NUMERIC "1"
-- Retrieval info: PRIVATE: REGrdaddress NUMERIC "1"
-- Retrieval info: PRIVATE: REGrren NUMERIC "1"
-- Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
-- Retrieval info: PRIVATE: REGwren NUMERIC "1"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
-- Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
-- Retrieval info: PRIVATE: VarWidth NUMERIC "0"
-- Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "16"
-- Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "16"
-- Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "16"
-- Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "16"
-- Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0"
-- Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: enable NUMERIC "0"
-- Retrieval info: PRIVATE: rden NUMERIC "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE"
-- Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "8192"
-- Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "8192"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT"
-- Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
-- Retrieval info: CONSTANT: OUTDATA_REG_B STRING "CLOCK0"
-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
-- Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE"
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "13"
-- Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "13"
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "16"
-- Retrieval info: CONSTANT: WIDTH_B NUMERIC "16"
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
-- Retrieval info: USED_PORT: data 0 0 16 0 INPUT NODEFVAL "data[15..0]"
-- Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL "q[15..0]"
-- Retrieval info: USED_PORT: rdaddress 0 0 13 0 INPUT NODEFVAL "rdaddress[12..0]"
-- Retrieval info: USED_PORT: wraddress 0 0 13 0 INPUT NODEFVAL "wraddress[12..0]"
-- Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren"
-- Retrieval info: CONNECT: @address_a 0 0 13 0 wraddress 0 0 13 0
-- Retrieval info: CONNECT: @address_b 0 0 13 0 rdaddress 0 0 13 0
-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
-- Retrieval info: CONNECT: @data_a 0 0 16 0 data 0 0 16 0
-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
-- Retrieval info: CONNECT: q 0 0 16 0 @q_b 0 0 16 0
-- Retrieval info: GEN_FILE: TYPE_NORMAL dual_ported_ram.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL dual_ported_ram.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL dual_ported_ram.cmp FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL dual_ported_ram.bsf FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL dual_ported_ram_inst.vhd FALSE
-- Retrieval info: LIB_FILE: altera_mf

View File

@@ -0,0 +1,288 @@
-- Lepton Avalon Memory-Mapped Slave Interface
-- Author: Philémon Favrod (philemon.favrod@epfl.ch)
-- Modified by: Sahand Kashani-Akhavan (sahand.kashani-akhavan@epfl.ch)
-- Revision: 2
-- Register map
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | RegNo | Name | Access | Description |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 0 | COMMAND | WO | Command |
-- | | | | - Writing 1 starts capturing a frame & resets the |
-- | | | | ERROR bit (bit 1) in the STATUS register. |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 1 | STATUS | RO | Status |
-- | | | | - Bit 0: 0 --> no capture in progress. |
-- | | | | 1 --> capture in progress. |
-- | | | | - Bit 1: 0 --> previous capture successful. |
-- | | | | 1 --> error during previous capture. |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 2 | MIN | RO | Minimum pixel value in frame. |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 3 | MAX | RO | Maximum pixel value in frame. |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 4 | SUM_LSB | RO | Sum of all pixels in frame (low 16 bits). |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 5 | SUM_MSB | RO | Sum of all pixels in frame (high 16 bits). |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 6 | ROW_IDX | RO | Current line being captured (1 <= ROW_IDX <= 60). |
-- | | | | Available for debugging purposes. |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 7 | RESERVED | - | Reserved |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 8 - 4807 | RAW BUFFER | RO | View into RAW pixel buffer. |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 4808 - 8191 | RESERVED | - | Reserved |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 8192 - 12991 | ADJUSTED BUFFER | RO | View into adjusted (scaled) pixel buffer. |
-- | | | | Values are scaled between MIN and MAX. |
-- +---------------+-----------------+--------+---------------------------------------------------+
-- | 12992 - 16383 | RESERVED | - | Reserved |
-- +---------------+-----------------+--------+---------------------------------------------------+
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity lepton is
port(
clk : in std_logic;
reset : in std_logic;
address : in std_logic_vector(13 downto 0);
readdata : out std_logic_vector(15 downto 0);
writedata : in std_logic_vector(15 downto 0);
read : in std_logic;
write : in std_logic;
SCLK : out std_logic;
CSn : out std_logic;
MOSI : out std_logic;
MISO : in std_logic
);
end lepton;
architecture rtl of lepton is
signal spi_cs_n : std_logic;
signal spi_mosi_data : std_logic_vector(7 downto 0);
signal spi_mosi_valid : std_logic;
signal spi_mosi_ready : std_logic;
signal spi_miso_data : std_logic_vector(7 downto 0);
signal spi_miso_valid : std_logic;
signal lepton_manager_start : std_logic;
signal lepton_manager_error : std_logic;
signal byte_data : std_logic_vector(7 downto 0);
signal byte_valid : std_logic;
signal byte_sof : std_logic;
signal byte_eof : std_logic;
signal pix_data : std_logic_vector(13 downto 0);
signal pix_valid : std_logic;
signal pix_sof : std_logic;
signal pix_eof : std_logic;
signal stat_min : std_logic_vector(13 downto 0);
signal stat_max : std_logic_vector(13 downto 0);
signal stat_sum : std_logic_vector(26 downto 0);
signal stat_valid : std_logic;
signal ram_data : std_logic_vector(15 downto 0);
signal ram_wren : std_logic;
signal ram_wraddress : std_logic_vector(12 downto 0);
signal ram_rdaddress : std_logic_vector(12 downto 0);
signal ram_q : std_logic_vector(15 downto 0);
signal row_idx : std_logic_vector(5 downto 0);
signal raw_pixel : std_logic_vector(13 downto 0);
signal raw_max : std_logic_vector(13 downto 0);
signal raw_min : std_logic_vector(13 downto 0);
signal raw_sum : std_logic_vector(26 downto 0);
signal adjusted_pixel : std_logic_vector(13 downto 0);
constant COMMAND_REG_OFFSET : std_logic_vector(address'range) := "00000000000000";
constant STATUS_REG_OFFSET : std_logic_vector(address'range) := "00000000000001";
constant MIN_REG_OFFSET : std_logic_vector(address'range) := "00000000000010";
constant MAX_REG_OFFSET : std_logic_vector(address'range) := "00000000000011";
constant SUM_LSB_REG_OFFSET : std_logic_vector(address'range) := "00000000000100";
constant SUM_MSB_REG_OFFSET : std_logic_vector(address'range) := "00000000000101";
constant ROW_IDX_REG_OFFSET : std_logic_vector(address'range) := "00000000000110";
constant BUFFER_REG_OFFSET : unsigned(address'range) := "00000000001000";
constant ADJUSTED_BUFFER_REG_OFFSET : unsigned(address'range) := "10000000000000";
constant IMAGE_SIZE : integer := 80 * 60;
constant BUFFER_REG_LIMIT : unsigned(address'range) := unsigned(BUFFER_REG_OFFSET) + IMAGE_SIZE;
constant ADJUSTED_BUFFER_LIMIT : unsigned(address'range) := unsigned(ADJUSTED_BUFFER_REG_OFFSET) + IMAGE_SIZE;
signal max_reg : std_logic_vector(stat_max'range);
signal min_reg : std_logic_vector(stat_min'range);
signal sum_reg : std_logic_vector(stat_sum'range);
signal error_reg : std_logic;
begin
spi_controller0 : entity work.avalon_st_spi_master
port map(
clk => clk,
reset => reset,
spi_cs_n => spi_cs_n,
mosi_sink_data => spi_mosi_data,
mosi_sink_valid => spi_mosi_valid,
mosi_sink_ready => spi_mosi_ready,
miso_src_data => spi_miso_data,
miso_src_valid => spi_miso_valid,
SCLK => SCLK,
MISO => MISO,
MOSI => MOSI,
CS_n => CSn
);
lepton_manager0 : entity work.lepton_manager
port map(
clk => clk,
reset => reset,
spi_miso_sink_data => spi_miso_data,
spi_miso_sink_valid => spi_miso_valid,
spi_mosi_src_data => spi_mosi_data,
spi_mosi_src_valid => spi_mosi_valid,
spi_mosi_src_ready => spi_mosi_ready,
lepton_out_data => byte_data,
lepton_out_valid => byte_valid,
lepton_out_sof => byte_sof,
lepton_out_eof => byte_eof,
row_idx => row_idx,
error => lepton_manager_error,
start => lepton_manager_start,
spi_cs_n => spi_cs_n
);
byte2pix0 : entity work.byte2pix
port map(
clk => clk,
reset => reset,
byte_data => byte_data,
byte_valid => byte_valid,
byte_sof => byte_sof,
byte_eof => byte_eof,
pix_data => pix_data,
pix_valid => pix_valid,
pix_sof => pix_sof,
pix_eof => pix_eof
);
lepton_stats0 : entity work.lepton_stats
port map(
reset => reset,
clk => clk,
pix_data => pix_data,
pix_valid => pix_valid,
pix_sof => pix_sof,
pix_eof => pix_eof,
stat_min => stat_min,
stat_max => stat_max,
stat_sum => stat_sum,
stat_valid => stat_valid
);
ram_writer0 : entity work.ram_writer
port map(
clk => clk,
reset => reset,
pix_data => pix_data,
pix_valid => pix_valid,
pix_sof => pix_sof,
pix_eof => pix_eof,
ram_data => ram_data,
ram_wren => ram_wren,
ram_wraddress => ram_wraddress
);
dual_ported_ram0 : entity work.dual_ported_ram
port map(
clock => clk,
data => ram_data,
rdaddress => ram_rdaddress,
wraddress => ram_wraddress,
wren => ram_wren,
q => ram_q
);
level_adjuster0 : entity work.level_adjuster
port map(
clk => clk,
raw_pixel => ram_q(13 downto 0),
raw_max => max_reg,
raw_min => min_reg,
raw_sum => sum_reg,
adjusted_pixel => adjusted_pixel
);
p_lepton_start : process(clk, reset)
begin
if reset = '1' then
lepton_manager_start <= '0';
error_reg <= '0';
elsif rising_edge(clk) then
if write = '1' and address = COMMAND_REG_OFFSET then
lepton_manager_start <= writedata(0);
error_reg <= '0';
elsif pix_eof = '1' then
lepton_manager_start <= '0';
elsif lepton_manager_error = '1' then
error_reg <= '1';
end if;
end if;
end process p_lepton_start;
p_stat_reg : process(clk, reset)
begin
if reset = '1' then
min_reg <= (others => '0');
max_reg <= (others => '0');
sum_reg <= (others => '0');
elsif rising_edge(clk) then
if stat_valid = '1' then
min_reg <= stat_min;
max_reg <= stat_max;
sum_reg <= stat_sum;
end if;
end if;
end process p_stat_reg;
p_read : process(clk, reset)
begin
if reset = '1' then
readdata <= (others => '0');
ram_rdaddress <= (others => '0');
elsif rising_edge(clk) then
readdata <= (others => '0');
if read = '1' then
case address is
when STATUS_REG_OFFSET =>
readdata(1) <= error_reg;
readdata(0) <= lepton_manager_start;
when MIN_REG_OFFSET =>
readdata <= "00" & min_reg;
when MAX_REG_OFFSET =>
readdata <= "00" & max_reg;
when SUM_MSB_REG_OFFSET =>
readdata <= "00000" & sum_reg(26 downto 16);
when SUM_LSB_REG_OFFSET =>
readdata <= sum_reg(15 downto 0);
when ROW_IDX_REG_OFFSET =>
readdata(5 downto 0) <= row_idx;
when others =>
if unsigned(address) >= BUFFER_REG_OFFSET and unsigned(address) < BUFFER_REG_LIMIT then
ram_rdaddress <= std_logic_vector(resize(unsigned(address) - BUFFER_REG_OFFSET, ram_rdaddress'length));
readdata <= ram_q;
elsif unsigned(address) >= ADJUSTED_BUFFER_REG_OFFSET and unsigned(address) < ADJUSTED_BUFFER_LIMIT then
ram_rdaddress <= std_logic_vector(resize(unsigned(address) - ADJUSTED_BUFFER_REG_OFFSET, ram_rdaddress'length));
readdata <= "00" & adjusted_pixel;
end if;
end case;
end if;
end if;
end process p_read;
end rtl;

View File

@@ -0,0 +1,235 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity lepton_manager is
generic(
INPUT_CLK_FREQ : integer := 50000000);
port(
clk : in std_logic := '0';
reset : in std_logic := '0';
-- Avalon ST Sink to receive SPI data
spi_miso_sink_data : in std_logic_vector(7 downto 0);
spi_miso_sink_valid : in std_logic;
-- Avalon ST Source to send SPI data
spi_mosi_src_data : out std_logic_vector(7 downto 0);
spi_mosi_src_valid : out std_logic;
spi_mosi_src_ready : in std_logic := '0';
-- Filtered output to retransmit cleaned data (without the discard packets, see Lepton Datasheet on page 31)
-- lepton_out_data is valid on rising edge when lepton_src_valid = '1'
lepton_out_data : out std_logic_vector(7 downto 0);
lepton_out_valid : out std_logic;
lepton_out_sof : out std_logic;
lepton_out_eof : out std_logic;
-- Some status
row_idx : out std_logic_vector(5 downto 0);
error : out std_logic;
-- Avalon MM Slave interface for configuration
start : in std_logic;
-- The SPI Chip Select (Active low !)
spi_cs_n : out std_logic := '0');
end entity lepton_manager;
architecture rtl of lepton_manager is
type state_t is (Idle, CSn, ReadHeader, ReadPayload, DiscardPayload, WaitBeforeIdle);
signal state, next_state : state_t;
signal header_3_last_nibbles : std_logic_vector(11 downto 0);
constant CLOCK_TICKS_PER_37_MS : integer := 37 * (INPUT_CLK_FREQ / 1e3); -- the timeout delay for a frame
constant CLOCK_TICKS_PER_200_MS : integer := 200 * (INPUT_CLK_FREQ / 1e3);
constant CLOCK_TICKS_PER_200_NS : integer := (200 * (INPUT_CLK_FREQ / 1e6)) / 1e3;
constant BYTES_PER_HEADER : integer := 4;
constant BYTES_PER_PAYLOAD : integer := 160;
constant NUMBER_OF_LINES_PER_FRAME : positive := 60;
signal counter, counter_max : integer range 1 to CLOCK_TICKS_PER_200_MS;
signal line_counter : integer range 1 to NUMBER_OF_LINES_PER_FRAME;
signal timeout_counter : integer range 1 to CLOCK_TICKS_PER_37_MS;
signal counter_enabled : boolean;
signal waited_long_enough : boolean;
signal header_end, payload_end : boolean;
begin
-- purpose: register for state
p_fsm : process(clk, reset)
begin
if reset = '1' then
state <= Idle;
elsif rising_edge(clk) then
state <= next_state;
end if;
end process p_fsm;
-- purpose: compute the next state
p_nsl : process(header_3_last_nibbles, header_end, payload_end, start, spi_miso_sink_valid, state, waited_long_enough, line_counter)
begin
next_state <= state;
case state is
when Idle =>
if waited_long_enough and start = '1' then
next_state <= CSn;
end if;
when CSn =>
if waited_long_enough then
next_state <= ReadHeader;
end if;
when ReadHeader =>
if header_end then
if header_3_last_nibbles(11 downto 8) = X"F" then
next_state <= DiscardPayload;
else
next_state <= ReadPayload;
end if;
end if;
when DiscardPayload | ReadPayload =>
if payload_end then
next_state <= ReadHeader;
if line_counter = NUMBER_OF_LINES_PER_FRAME then
next_state <= WaitBeforeIdle;
end if;
end if;
when WaitBeforeIdle =>
if spi_miso_sink_valid = '1' then
next_state <= Idle;
end if;
end case;
end process p_nsl;
p_counter : process(clk, reset)
begin
if reset = '1' then
counter <= 1;
line_counter <= 1;
elsif rising_edge(clk) then
if counter = counter_max and counter_enabled then
counter <= 1;
if state = ReadPayload then
if line_counter = NUMBER_OF_LINES_PER_FRAME then
line_counter <= 1;
else
line_counter <= line_counter + 1;
end if;
end if;
elsif counter_enabled then
counter <= counter + 1;
end if;
end if;
end process p_counter;
p_error : process(clk, reset)
begin
if reset = '1' then
error <= '0';
timeout_counter <= 1;
elsif rising_edge(clk) then
if state /= ReadHeader and state /= ReadPayload and state /= ReadHeader then
timeout_counter <= 1;
error <= '0';
else
if timeout_counter = CLOCK_TICKS_PER_37_MS then
error <= '1';
else
timeout_counter <= timeout_counter + 1;
end if;
end if;
if state = ReadPayload and header_3_last_nibbles /= std_logic_vector(to_unsigned(line_counter - 1, header_3_last_nibbles'length)) then
error <= '1';
end if;
end if;
end process p_error;
-- purpose: wire the datapath
p_datapath : process(counter, counter_enabled, counter_max, line_counter, spi_miso_sink_data, spi_miso_sink_valid, spi_mosi_src_ready, state)
variable counter_ended : boolean;
begin
counter_max <= 1;
counter_enabled <= true;
waited_long_enough <= false;
lepton_out_data <= (others => '0');
lepton_out_valid <= '0';
lepton_out_sof <= '0';
lepton_out_eof <= '0';
spi_mosi_src_valid <= '0';
spi_mosi_src_data <= (others => '0');
spi_cs_n <= '0';
header_end <= false;
payload_end <= false;
counter_ended := (counter = counter_max and counter_enabled);
case state is
when Idle =>
counter_max <= CLOCK_TICKS_PER_200_MS;
waited_long_enough <= counter_ended;
spi_cs_n <= '1';
when CSn =>
counter_max <= CLOCK_TICKS_PER_200_NS;
waited_long_enough <= counter_ended;
when ReadHeader =>
counter_max <= BYTES_PER_HEADER;
counter_enabled <= spi_miso_sink_valid = '1';
header_end <= counter_ended;
spi_mosi_src_valid <= spi_mosi_src_ready;
when ReadPayload =>
counter_max <= BYTES_PER_PAYLOAD;
counter_enabled <= spi_miso_sink_valid = '1';
lepton_out_data <= spi_miso_sink_data;
lepton_out_valid <= spi_miso_sink_valid;
payload_end <= counter_ended;
spi_mosi_src_valid <= spi_mosi_src_ready;
if spi_miso_sink_valid = '1' then
if counter = 1 and counter_enabled and line_counter = 1 then
lepton_out_sof <= '1';
elsif counter_ended and line_counter = NUMBER_OF_LINES_PER_FRAME then
lepton_out_eof <= '1';
end if;
end if;
when DiscardPayload =>
counter_max <= BYTES_PER_PAYLOAD;
counter_enabled <= spi_miso_sink_valid = '1';
payload_end <= counter_ended;
spi_mosi_src_valid <= spi_mosi_src_ready;
when others => null;
end case;
end process p_datapath;
p_capture_header : process(clk, reset)
begin
if reset = '1' then
header_3_last_nibbles <= X"000";
elsif rising_edge(clk) then
if state = ReadHeader and spi_miso_sink_valid = '1' then
if counter = 1 then
header_3_last_nibbles(11 downto 8) <= spi_miso_sink_data(3 downto 0);
elsif counter = 2 then
header_3_last_nibbles(7 downto 0) <= spi_miso_sink_data;
end if;
end if;
end if;
end process p_capture_header;
row_idx <= std_logic_vector(to_unsigned(line_counter, row_idx'length));
end architecture rtl;

View File

@@ -0,0 +1,78 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity lepton_stats is
port(
clk : in std_logic;
reset : in std_logic;
pix_data : in std_logic_vector(13 downto 0);
pix_valid : in std_logic;
pix_sof : in std_logic;
pix_eof : in std_logic;
stat_min : out std_logic_vector(13 downto 0);
stat_max : out std_logic_vector(13 downto 0);
stat_sum : out std_logic_vector(26 downto 0);
stat_valid : out std_logic);
end lepton_stats;
architecture rtl of lepton_stats is
-- The accumulated sum, min and max of the pixel values
signal curr_min : unsigned(13 downto 0);
signal curr_max : unsigned(13 downto 0);
signal curr_sum : unsigned(26 downto 0);
-- The next value of the registers
signal next_min : unsigned(13 downto 0);
signal next_max : unsigned(13 downto 0);
signal next_sum : unsigned(26 downto 0);
begin
-- This is the synchronous transition logic
transition_logic : process(clk, reset)
begin
if reset = '1' then
curr_sum <= (others => '0');
curr_min <= (others => '0');
curr_max <= (others => '0');
elsif rising_edge(clk) then
curr_min <= next_min;
curr_max <= next_max;
curr_sum <= next_sum;
end if;
end process;
-- This is the combinatorial transition logic
next_min <=
curr_min when pix_valid = '0' else
unsigned(pix_data) when pix_sof = '1' else
curr_min when unsigned(pix_data) >= curr_min else
unsigned(pix_data);
next_max <=
curr_max when pix_valid = '0' else
unsigned(pix_data) when pix_sof = '1' else
curr_max when unsigned(pix_data) <= curr_max else
unsigned(pix_data);
next_sum <=
curr_sum when pix_valid = '0' else
unsigned((26 downto 14 => '0') & pix_data) when pix_sof = '1' else
curr_sum + unsigned((26 downto 14 => '0') & pix_data);
-- This is the synchronous output logic
output_logic : process(clk, reset)
begin
if rising_edge(clk) then
stat_valid <= pix_eof;
end if;
end process;
-- This is the combinatorial output logic
stat_min <= std_logic_vector(curr_min);
stat_max <= std_logic_vector(curr_max);
stat_sum <= std_logic_vector(curr_sum);
end rtl;

View File

@@ -0,0 +1,50 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity level_adjuster is
port(
clk : in std_logic;
raw_pixel : in std_logic_vector(13 downto 0);
raw_max : in std_logic_vector(13 downto 0);
raw_min : in std_logic_vector(13 downto 0);
raw_sum : in std_logic_vector(26 downto 0);
adjusted_pixel : out std_logic_vector(13 downto 0));
end level_adjuster;
architecture rtl of level_adjuster is
component lpm_divider
port(
clock : in std_logic;
denom : in std_logic_vector(13 downto 0);
numer : in std_logic_vector(27 downto 0);
quotient : out std_logic_vector(27 downto 0);
remain : out std_logic_vector(13 downto 0));
end component;
-- Intermediate signals needed by the divider
signal numer : std_logic_vector(27 downto 0);
signal denom : std_logic_vector(13 downto 0);
signal quot : std_logic_vector(27 downto 0);
begin
-- Computation of the intermediate signals
numer <= std_logic_vector((13 downto 0 => '1') * (unsigned(raw_pixel) - unsigned(raw_min)));
denom <= std_logic_vector(unsigned(raw_max) - unsigned(raw_min));
-- We compute the remaineder of (x - min) / (max - min)
divider : lpm_divider port map(
clock => clk,
numer => numer,
denom => denom,
quotient => quot,
remain => open
);
-- And we only keep the LSB of the quotient (we know the MSB must be 0)
adjusted_pixel <=
(adjusted_pixel'range => '0') when denom = (denom'range => '0') else
quot(13 downto 0);
end rtl;

View File

@@ -0,0 +1,133 @@
-- megafunction wizard: %LPM_DIVIDE%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: LPM_DIVIDE
-- ============================================================
-- File Name: lpm_divider.vhd
-- Megafunction Name(s):
-- LPM_DIVIDE
--
-- Simulation Library Files(s):
-- lpm
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 15.1.0 Build 185 10/21/2015 SJ Lite Edition
-- ************************************************************
--Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
--Your use of Altera Corporation's design tools, logic functions
--and other software and tools, and its AMPP partner logic
--functions, and any output files from any of the foregoing
--(including device programming or simulation files), and any
--associated documentation or information are expressly subject
--to the terms and conditions of the Altera Program License
--Subscription Agreement, the Altera Quartus Prime License Agreement,
--the Altera MegaCore Function License Agreement, or other
--applicable license agreement, including, without limitation,
--that your use is for the sole purpose of programming logic
--devices manufactured by Altera and sold by Altera or its
--authorized distributors. Please refer to the applicable
--agreement for further details.
library ieee;
use ieee.std_logic_1164.all;
library lpm;
use lpm.all;
entity lpm_divider is
port(
clock : in std_logic;
denom : in std_logic_vector(13 downto 0);
numer : in std_logic_vector(27 downto 0);
quotient : out std_logic_vector(27 downto 0);
remain : out std_logic_vector(13 downto 0)
);
end lpm_divider;
architecture SYN of lpm_divider is
signal sub_wire0 : std_logic_vector(27 downto 0);
signal sub_wire1 : std_logic_vector(13 downto 0);
component lpm_divide
generic(
lpm_drepresentation : string;
lpm_hint : string;
lpm_nrepresentation : string;
lpm_pipeline : natural;
lpm_type : string;
lpm_widthd : natural;
lpm_widthn : natural
);
port(
clock : in std_logic;
denom : in std_logic_vector(13 downto 0);
numer : in std_logic_vector(27 downto 0);
quotient : out std_logic_vector(27 downto 0);
remain : out std_logic_vector(13 downto 0)
);
end component;
begin
quotient <= sub_wire0(27 downto 0);
remain <= sub_wire1(13 downto 0);
LPM_DIVIDE_component : LPM_DIVIDE
generic map(
lpm_drepresentation => "UNSIGNED",
lpm_hint => "LPM_REMAINDERPOSITIVE=TRUE",
lpm_nrepresentation => "UNSIGNED",
lpm_pipeline => 5,
lpm_type => "LPM_DIVIDE",
lpm_widthd => 14,
lpm_widthn => 28
)
port map(
clock => clock,
denom => denom,
numer => numer,
quotient => sub_wire0,
remain => sub_wire1
);
end SYN;
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
-- Retrieval info: PRIVATE: PRIVATE_LPM_REMAINDERPOSITIVE STRING "TRUE"
-- Retrieval info: PRIVATE: PRIVATE_MAXIMIZE_SPEED NUMERIC "-1"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: USING_PIPELINE NUMERIC "1"
-- Retrieval info: PRIVATE: VERSION_NUMBER NUMERIC "2"
-- Retrieval info: PRIVATE: new_diagram STRING "1"
-- Retrieval info: LIBRARY: lpm lpm.lpm_components.all
-- Retrieval info: CONSTANT: LPM_DREPRESENTATION STRING "UNSIGNED"
-- Retrieval info: CONSTANT: LPM_HINT STRING "LPM_REMAINDERPOSITIVE=TRUE"
-- Retrieval info: CONSTANT: LPM_NREPRESENTATION STRING "UNSIGNED"
-- Retrieval info: CONSTANT: LPM_PIPELINE NUMERIC "5"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "LPM_DIVIDE"
-- Retrieval info: CONSTANT: LPM_WIDTHD NUMERIC "14"
-- Retrieval info: CONSTANT: LPM_WIDTHN NUMERIC "28"
-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL "clock"
-- Retrieval info: USED_PORT: denom 0 0 14 0 INPUT NODEFVAL "denom[13..0]"
-- Retrieval info: USED_PORT: numer 0 0 28 0 INPUT NODEFVAL "numer[27..0]"
-- Retrieval info: USED_PORT: quotient 0 0 28 0 OUTPUT NODEFVAL "quotient[27..0]"
-- Retrieval info: USED_PORT: remain 0 0 14 0 OUTPUT NODEFVAL "remain[13..0]"
-- Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
-- Retrieval info: CONNECT: @denom 0 0 14 0 denom 0 0 14 0
-- Retrieval info: CONNECT: @numer 0 0 28 0 numer 0 0 28 0
-- Retrieval info: CONNECT: quotient 0 0 28 0 @quotient 0 0 28 0
-- Retrieval info: CONNECT: remain 0 0 14 0 @remain 0 0 14 0
-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_divider.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_divider.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_divider.cmp FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_divider.bsf FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_divider_inst.vhd FALSE
-- Retrieval info: LIB_FILE: lpm

View File

@@ -0,0 +1,38 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ram_writer is
port(
clk, reset : in std_logic;
pix_data : in std_logic_vector(13 downto 0);
pix_valid : in std_logic;
pix_sof : in std_logic;
pix_eof : in std_logic;
ram_data : out std_logic_vector(15 downto 0);
ram_wren : out std_logic;
ram_wraddress : out std_logic_vector(12 downto 0));
end ram_writer;
architecture rtl of ram_writer is
signal wraddress_counter : unsigned(ram_wraddress'range);
begin
p_address_gen : process(clk, reset)
begin
if reset = '1' then
wraddress_counter <= (others => '0');
elsif rising_edge(clk) then
if pix_eof = '1' then
wraddress_counter <= (others => '0');
elsif pix_valid = '1' then
wraddress_counter <= wraddress_counter + 1;
end if;
end if;
end process p_address_gen;
ram_data <= "00" & pix_data;
ram_wren <= pix_valid;
ram_wraddress <= std_logic_vector(wraddress_counter);
end rtl;

View File

@@ -0,0 +1,27 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package utils is
function bitlength(number : positive) return positive;
end package utils;
package body utils is
-- purpose: returns the minimum # of bits needed to represent the input number
function bitlength(number : positive) return positive is
variable acc : positive := 1;
variable i : natural := 0;
begin
while True loop
if acc > number then
return i;
end if;
acc := acc * 2;
i := i + 1;
end loop;
end function bitlength;
end package body utils;

View File

@@ -0,0 +1,77 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity lepton_tb is
end lepton_tb;
architecture tb of lepton_tb is
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal address : std_logic_vector(13 downto 0) := (others => '0');
signal readdata : std_logic_vector(15 downto 0) := (others => '0');
signal writedata : std_logic_vector(15 downto 0) := (others => '0');
signal read : std_logic := '0';
signal write : std_logic := '0';
signal SCLK : std_logic := '0';
signal CSn : std_logic := '0';
signal MOSI : std_logic := '0';
signal MISO : std_logic := '1';
constant CLK_PERIOD : time := 20 ns;
signal sim_ended : boolean := false;
begin
dut : entity work.lepton
port map(
clk => clk,
reset => reset,
address => address,
readdata => readdata,
writedata => writedata,
read => read,
write => write,
SCLK => SCLK,
CSn => CSn,
MOSI => MOSI,
MISO => MISO
);
clk <= not clk after CLK_PERIOD / 2 when not sim_ended else '0';
miso_gen : process
variable seed1, seed2 : positive;
variable rand : real;
begin
if sim_ended then
wait;
else
uniform(seed1, seed2, rand);
wait until rising_edge(SCLK);
MISO <= to_unsigned(integer(rand), 1)(0);
end if;
end process;
stimuli : process
begin
reset <= '1';
write <= '0';
wait for 2 * CLK_PERIOD;
reset <= '0';
wait for CLK_PERIOD;
write <= '1';
writedata(0) <= '1';
wait for CLK_PERIOD;
write <= '0';
wait for 17 ms;
sim_ended <= true;
wait;
end process;
end tb;