Skip to content
Snippets Groups Projects
Unverified Commit fc6a4e6b authored by Joakim Argillander's avatar Joakim Argillander
Browse files

Stashed for safekeeping

parent 7451e03b
Branches master
No related tags found
No related merge requests found
-------------------------------------------------------------------------
-- AD1RefComp.VHD
-------------------------------------------------------------------------
-- Author : Ioana Dabacan
-- CopyRight 2008 Digilent Ro.
-------------------------------------------------------------------------
-- Description : This file is the VHDL code for a PMOD-AD1 controller.
--
-------------------------------------------------------------------------
-- Revision History:
-- Feb/29/2008 Created (Ioana Dabacan)
-------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
package ADC is
component AD1RefComp is
Port (
--General usage
CLK : in std_logic;
RST : in std_logic;
--Pmod interface signals
SDATA1 : in std_logic;
SDATA2 : in std_logic;
SCLK : out std_logic;
nCS : out std_logic;
--User interface signals
DATA1 : out std_logic_vector(11 downto 0);
DATA2 : out std_logic_vector(11 downto 0);
START : in std_logic;
DONE : out std_logic
);
end component AD1RefComp;
end package ADC;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-------------------------------------------------------------------------
--Title : AD1 Reference Component
--
-- Inputs : 5
-- Outputs : 5
--
-- Description: This is the AD1 Reference Component entity. The input
-- ports are a 50 MHz clock and an asynchronous reset
-- button along with the data from the ADC7476 that
-- is serially shifted in on each clock cycle(SDATA1 and
-- SDATA2). The outputs are the SCLK signal which clocks
-- the PMOD-AD1 board at 12.5 MHz and a chip select
-- signal (nCS) that enables the ADC7476 chips on the
-- PMOD-AD1 board as well as two 12-bit output
-- vectors labeled DATA1 and DATA2 which can be used by
-- any external components. The START is used to tell
-- the component when to start a conversion. After a
-- conversion is done the component activates the DONE
-- signal.
--
--------------------------------------------------------------------------
entity AD1RefComp is
Port (
--General usage
CLK : in std_logic;
RST : in std_logic;
--Pmod interface signals
SDATA1 : in std_logic;
SDATA2 : in std_logic;
SCLK : out std_logic;
nCS : out std_logic;
--User interface signals
DATA1 : out std_logic_vector(11 downto 0);
DATA2 : out std_logic_vector(11 downto 0);
START : in std_logic;
DONE : out std_logic
);
end AD1RefComp ;
architecture AD1 of AD1RefComp is
--------------------------------------------------------------------------------
-- Title : Local signal assignments
--
-- Description : The following signals will be used to drive the
-- processes of this VHDL file.
--
-- current_state : This signal will be the pointer that will point at the
-- current state of the Finite State Machine of the
-- controller.
-- next_state : This signal will be the pointer that will point at the
-- current state of the Finite State Machine of the
-- controller.
-- temp1 : This is a 16-bit vector that will store the 16-bits of data
-- that are serially shifted-in form the first ADC7476 chip
-- inside the PMOD-AD1 board.
-- temp2 : This is a 16-bit vector that will store the 16-bits of data
-- that are serially shifted-in form the second ADC7476 chip
-- inside the PMOD-AD1 board.
-- clk_div : This will be the divided 12.5 MHz clock signal that will
-- clock the PMOD-AD1 board
-- clk_counter : This counter will be used to create a divided clock signal.
--
-- shiftCounter : This counter will be used to count the shifted data from
-- the ADC7476 chip inside the PMOD-AD1 board.
-- enShiftCounter: This signal will be used to enable the counter for the
-- shifted data from the ADC7476 chip inside the PMOD-AD1.
-- enParalelLoad : This signal will be used to enable the load the shifted
-- data in a register.
--------------------------------------------------------------------------------
type states is (Idle,
ShiftIn,
SyncData);
signal current_state : states;
signal next_state : states;
signal temp1 : std_logic_vector(15 downto 0);
signal temp2 : std_logic_vector(15 downto 0);
signal clk_div : std_logic;
signal clk_counter : std_logic_vector(1 downto 0);
signal shiftCounter : std_logic_vector(3 downto 0) := x"0";
signal enShiftCounter: std_logic;
signal enParalelLoad : std_logic;
begin
--------------------------------------------------------------------------------
-- Title : clock divider process
--
-- Description : This is the process that will divide the 50 MHz clock
-- down to a clock speed of 12.5 MHz to drive the ADC7476 chip.
--------------------------------------------------------------------------------
clock_divide : process(rst,clk)
begin
if rst = '1' then
clk_counter <= "00";
elsif (clk = '1' and clk'event) then
clk_counter <= clk_counter + '1';
end if;
end process;
clk_div <= clk_counter(1);
SCLK <= not clk_counter(1);
-----------------------------------------------------------------------------------
--
-- Title : counter
--
-- Description: This is the process were the converted data will be colected and
-- output.When the enShiftCounter is activated, the 16-bits of data
-- from the ADC7476 chips will be shifted inside the temporary
-- registers. A 4-bit counter is used to keep shifting the data
-- inside temp1 and temp2 for 16 clock cycles. When the enParalelLoad
-- signal is generated inside the SyncData state, the converted data
-- in the temporary shift registers will be placed on the outputs
-- DATA1 and DATA2.
--
-----------------------------------------------------------------------------------
counter : process(clk_div, enParalelLoad, enShiftCounter)
begin
if (clk_div = '1' and clk_div'event) then
if (enShiftCounter = '1') then
temp1 <= temp1(14 downto 0) & SDATA1;
temp2 <= temp2(14 downto 0) & SDATA2;
shiftCounter <= shiftCounter + '1';
elsif (enParalelLoad = '1') then
shiftCounter <= "0000";
DATA1 <= temp1(11 downto 0);
DATA2 <= temp2(11 downto 0);
end if;
end if;
end process;
---------------------------------------------------------------------------------
--
-- Title : Finite State Machine
--
-- Description: This 3 processes represent the FSM that contains three states.
-- The first state is the Idle state in which a temporary registers
-- are assigned the updated value of the input "DATA1" and "DATA2".
-- The next state is the ShiftIn state where the 16-bits of data
-- from each of the ADCS7476 chips are left shifted in the temp1
-- and temp2 shift registers. The third state, SyncData drives the
-- output signal nCS high for 1 clock period maintainig nCS high
-- also in the Idle state telling the ADCS7476 to mark the end of
-- the conversion.
-- Notes: The data will change on the lower edge of the clock signal. There
-- is also an asynchronous reset that will reset all signals to
-- their original state.
--
-----------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
--
-- Title : SYNC_PROC
--
-- Description: This is the process were the states are changed synchronously. At
-- reset the current state becomes Idle state.
--
-----------------------------------------------------------------------------------
SYNC_PROC: process (clk_div, rst)
begin
if (clk_div'event and clk_div = '1') then
if (rst = '1') then
current_state <= Idle;
else
current_state <= next_state;
end if;
end if;
end process;
-----------------------------------------------------------------------------------
--
-- Title : OUTPUT_DECODE
--
-- Description: This is the process were the output signals are generated
-- unsynchronously based on the state only (Moore State Machine).
--
-----------------------------------------------------------------------------------
OUTPUT_DECODE: process (current_state)
begin
if current_state = Idle then
enShiftCounter <='0';
DONE <='1';
nCS <='1';
enParalelLoad <= '0';
elsif current_state = ShiftIn then
enShiftCounter <='1';
DONE <='0';
nCS <='0';
enParalelLoad <= '0';
else --if current_state = SyncData then
enShiftCounter <='0';
DONE <='0';
nCS <='1';
enParalelLoad <= '1';
end if;
end process;
----------------------------------------------------------------------------------
--
-- Title : NEXT_STATE_DECODE
--
-- Description: This is the process were the next state logic is generated
-- depending on the current state and the input signals.
--
-----------------------------------------------------------------------------------
NEXT_STATE_DECODE: process (current_state, START, shiftCounter)
begin
next_state <= current_state; -- default is to stay in current state
case (current_state) is
when Idle =>
if START = '1' then
next_state <= ShiftIn;
end if;
when ShiftIn =>
if shiftCounter = x"F" then
next_state <= SyncData;
end if;
when SyncData =>
if START = '0' then
next_state <= Idle;
end if;
when others =>
next_state <= Idle;
end case;
end process;
end AD1;
\ No newline at end of file
File added
--------------------------------------------------------------------------------
-- DA2 Reference Component
--------------------------------------------------------------------------------
-- Author : Ioana Dabacan
-- CopyRight 2008 Digilent Ro.
--------------------------------------------------------------------------------
-- Desription : This file is the VHDL code for a PMOD-DA2 controller.
--
--------------------------------------------------------------------------------
-- Revision History:
-- Feb/29/2008 (Created) Ioana Dabacan
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--------------------------------------------------------------------------------
--
-- Title : DA1 controller entity
--
-- Inputs : 5
-- Outputs : 5
--
-- Description: This is the DA2 Reference Component entity. The input ports are
-- a 50MHz clock and and an asynchronous reset button along with the
-- data to be serially shifted in the 2 DAC121S101 chips on a DA2
-- Pmod on each clock cycle.There is also a signal to start a
-- conversion.
-- The outputs of this entity are: a output clock signal, two serial
-- output signals D1 and D2, a sync signal to synchronize the data
-- in the DAC121S101 chip, a done signal to tell that the chip is
-- done converting the data and another set of data can be sent.
--
---------------------------------------------------------------------------------
entity DA2RefComp is
Port (
--General usage
CLK : in std_logic; -- System Clock (50MHz)
RST : in std_logic;
--Pmod interface signals
D1 : out std_logic;
--D2 : out std_slogic;
CLK_OUT : out std_logic;
nSYNC : out std_logic;
--User interface signal
DATA1 : in std_logic_vector(7 downto 0);
-- DATA2 : in std_logic_vector(11 downto 0);
--START : in std_logic;
DONE : buffer std_logic
);
end DA2RefComp ;
architecture DA2 of DA2RefComp is
-- control constant: Normal Operation
constant control : std_logic_vector(3 downto 0) := "0000";
------------------------------------------------------------------------------------
-- Title : signal assignments
--
-- Description: The following signals are enumerated signals for the
-- finite state machine,2 temporary vectors to be shifted out to the
-- DAC121S101 chips, a divided clock signal to drive the DAC121S101 chips,
-- a counter to divide the internal 50 MHz clock signal,
-- a 4-bit counter to be used to shift out the 16-bit register,
-- and 2 enable signals for the paralel load and shift of the
-- shift register.
--
------------------------------------------------------------------------------------
type states is (Idle,
ShiftOut,
SyncData);
signal current_state : states;
signal next_state : states;
signal temp1 : std_logic_vector(15 downto 0) := (others => '0');
signal temp2 : std_logic_vector(15 downto 0) := (others => '0');
signal clk_div : std_logic := '0';
signal clk_counter : std_logic_vector(27 downto 0) := (others => '0');
signal shiftCounter : std_logic_vector(3 downto 0) := (others => '0');
signal enShiftCounter: std_logic := '0';
signal enParalelLoad : std_logic := '0';
signal data_int : std_logic_vector(11 downto 0) := (others => '0');
signal START : std_logic := '1';
signal sweep_clk : std_logic := '0';
signal sweep_ctr : std_logic_vector(11 downto 0) := (others => '0');
begin
------------------------------------------------------------------------------------
--
-- Title : Clock Divider
--
-- Description: The following process takes a 50 MHz clock and divides it down to a
-- 25 MHz clock signal by assigning the signals clk_out and clk_div
-- to the 2nd bit of the clk_counter vector. clk_div is used by
-- the Finite State Machine and clk_out is used by the DAC121S101 chips.
--
------------------------------------------------------------------------------------
clock_divide : process(rst,clk)
begin
if rising_edge(clk) then
if rst = '1' then
clk_counter <= "0000000000000000000000000000";
else
clk_counter <= clk_counter + '1';
end if;
end if;
end process;
clk_div <= clk_counter(1);
clk_out <= clk_counter(1);
sweep_clk <= clk_counter(6);
process(sweep_clk) begin
if(rising_edge(sweep_clk)) then
if(unsigned(sweep_ctr) >= 4095) then
sweep_ctr <= (others => '0');
else
sweep_ctr <= sweep_ctr + '1';
end if;
end if;
end process;
data_int <= sweep_ctr;
-----------------------------------------------------------------------------------
--
-- Title : counter
--
-- Description: This is the process were the teporary registers will be loaded and
-- shifted.When the enParalelLoad signal is generated inside the state
-- the temp1 and temp2 registers will be loaded with the 8 bits of control
-- concatenated with the 8 bits of data. When the enShiftCounter is
-- activated, the 16-bits of data inside the temporary registers will be
-- shifted. A 4-bit counter is used to keep shifting the data
-- inside temp1 and temp 2 for 16 clock cycles.
--
-----------------------------------------------------------------------------------
--data_int(11 downto 4) <= DATA1;
--data_int(3 downto 0) <= "1111";
counter : process(clk_div, enParalelLoad, enShiftCounter)
begin
if rising_edge(clk_div) then
if enParalelLoad = '1' then
shiftCounter <= "0000";
temp1 <= control & data_int;
--temp2 <= control & DATA2;
elsif (enShiftCounter = '1') then
temp1 <= temp1(14 downto 0)&temp1(15);
temp2 <= temp2(14 downto 0)&temp2(15);
shiftCounter <= shiftCounter + '1';
end if;
end if;
end process;
D1 <= temp1(15);
--D2 <= temp2(15);
---------------------------------------------------------------------------------
--
-- Title : Finite State Machine
--
-- Description: This 3 processes represent the FSM that contains three states.
-- First one is the Idle state in which the temporary registers are
-- assigned the updated value of the input "DATA1" and "DATA2".
-- The next state is the ShiftOut state which is the state where the
-- 16-bits of temporary registers are shifted out left from the MSB
-- to the two serial outputs, D1 and D2. Immediately following the
-- second state is the third state SyncData. This state drives the
-- output signal sync high for2 clock signals telling the DAC121S101
-- to latch the 16-bit data it just recieved in the previous state.
-- Notes: The data will change on the upper edge of the clock signal. Their
-- is also an asynchronous reset that will reset all signals to their
-- original state.
--
-----------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
--
-- Title : SYNC_PROC
--
-- Description: This is the process were the states are changed synchronously. At
-- reset the current state becomes Idle state.
--
-----------------------------------------------------------------------------------
SYNC_PROC: process (clk_div, rst)
begin
if rising_edge(clk_div) then
if (rst = '1') then
current_state <= Idle;
else
current_state <= next_state;
end if;
end if;
end process;
-----------------------------------------------------------------------------------
--
-- Title : OUTPUT_DECODE
--
-- Description: This is the process were the output signals are generated
-- unsynchronously based on the state only (Moore State Machine).
--
-----------------------------------------------------------------------------------
OUTPUT_DECODE: process (current_state)
begin
if current_state = Idle then
enShiftCounter <='0';
DONE <='1';
nSYNC <='1';
enParalelLoad <= '1';
elsif current_state = ShiftOut then
enShiftCounter <='1';
DONE <='0';
nSYNC <='0';
enParalelLoad <= '0';
else --if current_state = SyncData then
enShiftCounter <='0';
DONE <='0';
nSYNC <='1';
enParalelLoad <= '0';
end if;
end process;
-----------------------------------------------------------------------------------
--
-- Title : NEXT_STATE_DECODE
--
-- Description: This is the process were the next state logic is generated
-- depending on the current state and the input signals.
--
-----------------------------------------------------------------------------------
NEXT_STATE_DECODE: process (current_state, START, shiftCounter, CLK) -- added clk
begin
next_state <= current_state; --default is to stay in current state
case (current_state) is
when Idle =>
if START = '1' and DONE = '1' then
next_state <= ShiftOut;
end if;
when ShiftOut =>
if shiftCounter = x"F" then
next_state <= SyncData;
end if;
when SyncData =>
if START = '1' then -- was 0
next_state <= Idle;
end if;
when others =>
next_state <= Idle;
end case;
end process;
end DA2;
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
entity DAC_controller_v1_0_S00_AXI is
generic (
-- Users to add parameters here
-- User parameters ends
-- Do not modify the parameters beyond this line
-- Width of S_AXI data bus
C_S_AXI_DATA_WIDTH : integer := 32;
-- Width of S_AXI address bus
C_S_AXI_ADDR_WIDTH : integer := 6
);
port (
-- Users to add ports here
S_GCLK : in std_logic;
S_GRESET : in std_logic;
S_D1 : out std_logic;
S_D2 : out std_logic;
S_CLK_OUT : out std_logic;
S_NSYNC : out std_logic;
S_DONE : out std_logic;
S_EXT_START : in std_logic;
S_LEDS_OUT : out std_logic_vector(7 downto 0);
-- User ports ends
-- Do not modify the ports beyond this line
-- Global Clock Signal
S_AXI_ACLK : in std_logic;
-- Global Reset Signal. This Signal is Active LOW
S_AXI_ARESETN : in std_logic;
-- Write address (issued by master, acceped by Slave)
S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
-- Write channel Protection type. This signal indicates the
-- privilege and security level of the transaction, and whether
-- the transaction is a data access or an instruction access.
S_AXI_AWPROT : in std_logic_vector(2 downto 0);
-- Write address valid. This signal indicates that the master signaling
-- valid write address and control information.
S_AXI_AWVALID : in std_logic;
-- Write address ready. This signal indicates that the slave is ready
-- to accept an address and associated control signals.
S_AXI_AWREADY : out std_logic;
-- Write data (issued by master, acceped by Slave)
S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
-- Write strobes. This signal indicates which byte lanes hold
-- valid data. There is one write strobe bit for each eight
-- bits of the write data bus.
S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0);
-- Write valid. This signal indicates that valid write
-- data and strobes are available.
S_AXI_WVALID : in std_logic;
-- Write ready. This signal indicates that the slave
-- can accept the write data.
S_AXI_WREADY : out std_logic;
-- Write response. This signal indicates the status
-- of the write transaction.
S_AXI_BRESP : out std_logic_vector(1 downto 0);
-- Write response valid. This signal indicates that the channel
-- is signaling a valid write response.
S_AXI_BVALID : out std_logic;
-- Response ready. This signal indicates that the master
-- can accept a write response.
S_AXI_BREADY : in std_logic;
-- Read address (issued by master, acceped by Slave)
S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
-- Protection type. This signal indicates the privilege
-- and security level of the transaction, and whether the
-- transaction is a data access or an instruction access.
S_AXI_ARPROT : in std_logic_vector(2 downto 0);
-- Read address valid. This signal indicates that the channel
-- is signaling valid read address and control information.
S_AXI_ARVALID : in std_logic;
-- Read address ready. This signal indicates that the slave is
-- ready to accept an address and associated control signals.
S_AXI_ARREADY : out std_logic;
-- Read data (issued by slave)
S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
-- Read response. This signal indicates the status of the
-- read transfer.
S_AXI_RRESP : out std_logic_vector(1 downto 0);
-- Read valid. This signal indicates that the channel is
-- signaling the required read data.
S_AXI_RVALID : out std_logic;
-- Read ready. This signal indicates that the master can
-- accept the read data and response information.
S_AXI_RREADY : in std_logic
);
end DAC_controller_v1_0_S00_AXI;
architecture arch_imp of DAC_controller_v1_0_S00_AXI is
-- AXI4LITE signals
signal axi_awaddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
signal axi_awready : std_logic;
signal axi_wready : std_logic;
signal axi_bresp : std_logic_vector(1 downto 0);
signal axi_bvalid : std_logic;
signal axi_araddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
signal axi_arready : std_logic;
signal axi_rdata : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal axi_rresp : std_logic_vector(1 downto 0);
signal axi_rvalid : std_logic;
-- Example-specific design signals
-- local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH
-- ADDR_LSB is used for addressing 32/64 bit registers/memories
-- ADDR_LSB = 2 for 32 bits (n downto 2)
-- ADDR_LSB = 3 for 64 bits (n downto 3)
constant ADDR_LSB : integer := (C_S_AXI_DATA_WIDTH/32)+ 1;
constant OPT_MEM_ADDR_BITS : integer := 3;
------------------------------------------------
---- Signals for user logic register space example
-- control constant: Normal Operation
constant control : std_logic_vector(3 downto 0) := "0000";
------------------------------------------------------------------------------------
-- Title : signal assignments
--
-- Description: The following signals are enumerated signals for the
-- finite state machine,2 temporary vectors to be shifted out to the
-- DAC121S101 chips, a divided clock signal to drive the DAC121S101 chips,
-- a counter to divide the internal 50 MHz clock signal,
-- a 4-bit counter to be used to shift out the 16-bit register,
-- and 2 enable signals for the paralel load and shift of the
-- shift register.
--
------------------------------------------------------------------------------------
type states is (Idle,
ShiftOut,
SyncData);
signal current_state : states;
signal next_state : states;
signal temp1 : std_logic_vector(15 downto 0);
signal temp2 : std_logic_vector(15 downto 0);
signal clk_div : std_logic;
signal clk_counter : std_logic_vector(27 downto 0);
signal shiftCounter : std_logic_vector(3 downto 0);
signal enShiftCounter: std_logic;
signal enParalelLoad : std_logic;
signal DATA1 :std_logic_vector(11 downto 0);
signal DATA2 :std_logic_vector(11 downto 0);
signal START : std_logic;
--------------------------------------------------
---- Number of Slave Registers 16
signal slv_reg0 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg1 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg2 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg3 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg4 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg5 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg6 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg7 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg8 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg9 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg10 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg11 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg12 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg13 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg14 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg15 :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg_rden : std_logic;
signal slv_reg_wren : std_logic;
signal reg_data_out :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal byte_index : integer;
signal aw_en : std_logic;
begin
-- I/O Connections assignments
S_AXI_AWREADY <= axi_awready;
S_AXI_WREADY <= axi_wready;
S_AXI_BRESP <= axi_bresp;
S_AXI_BVALID <= axi_bvalid;
S_AXI_ARREADY <= axi_arready;
S_AXI_RDATA <= axi_rdata;
S_AXI_RRESP <= axi_rresp;
S_AXI_RVALID <= axi_rvalid;
-- Implement axi_awready generation
-- axi_awready is asserted for one S_AXI_ACLK clock cycle when both
-- S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is
-- de-asserted when reset is low.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_awready <= '0';
aw_en <= '1';
else
if (axi_awready = '0' and S_AXI_AWVALID = '1' and S_AXI_WVALID = '1' and aw_en = '1') then
-- slave is ready to accept write address when
-- there is a valid write address and write data
-- on the write address and data bus. This design
-- expects no outstanding transactions.
axi_awready <= '1';
aw_en <= '0';
elsif (S_AXI_BREADY = '1' and axi_bvalid = '1') then
aw_en <= '1';
axi_awready <= '0';
else
axi_awready <= '0';
end if;
end if;
end if;
end process;
-- Implement axi_awaddr latching
-- This process is used to latch the address when both
-- S_AXI_AWVALID and S_AXI_WVALID are valid.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_awaddr <= (others => '0');
else
if (axi_awready = '0' and S_AXI_AWVALID = '1' and S_AXI_WVALID = '1' and aw_en = '1') then
-- Write Address latching
axi_awaddr <= S_AXI_AWADDR;
end if;
end if;
end if;
end process;
-- Implement axi_wready generation
-- axi_wready is asserted for one S_AXI_ACLK clock cycle when both
-- S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is
-- de-asserted when reset is low.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_wready <= '0';
else
if (axi_wready = '0' and S_AXI_WVALID = '1' and S_AXI_AWVALID = '1' and aw_en = '1') then
-- slave is ready to accept write data when
-- there is a valid write address and write data
-- on the write address and data bus. This design
-- expects no outstanding transactions.
axi_wready <= '1';
else
axi_wready <= '0';
end if;
end if;
end if;
end process;
-- Implement memory mapped register select and write logic generation
-- The write data is accepted and written to memory mapped registers when
-- axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to
-- select byte enables of slave registers while writing.
-- These registers are cleared when reset (active low) is applied.
-- Slave register write enable is asserted when valid address and data are available
-- and the slave is ready to accept the write address and write data.
slv_reg_wren <= axi_wready and S_AXI_WVALID and axi_awready and S_AXI_AWVALID ;
process (S_AXI_ACLK)
variable loc_addr :std_logic_vector(OPT_MEM_ADDR_BITS downto 0);
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
slv_reg0 <= (others => '0');
slv_reg1 <= (others => '0');
slv_reg2 <= (others => '0');
slv_reg3 <= (others => '0');
slv_reg4 <= (others => '0');
slv_reg5 <= (others => '0');
slv_reg6 <= (others => '0');
slv_reg7 <= (others => '0');
slv_reg8 <= (others => '0');
slv_reg9 <= (others => '0');
--slv_reg10 <= (others => '0');
slv_reg11 <= (others => '0');
slv_reg12 <= (others => '0');
slv_reg13 <= (others => '0');
slv_reg14 <= (others => '0');
slv_reg15 <= (others => '0');
else
loc_addr := axi_awaddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB);
if (slv_reg_wren = '1') then
case loc_addr is
when b"0000" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 0
slv_reg0(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"0001" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 1
slv_reg1(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"0010" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 2
slv_reg2(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"0011" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 3
slv_reg3(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"0100" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 4
slv_reg4(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"0101" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 5
slv_reg5(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"0110" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 6
slv_reg6(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"0111" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 7
slv_reg7(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"1000" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 8
slv_reg8(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"1001" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 9
slv_reg9(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"1010" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 10
-- slv_reg10(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"1011" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 11
slv_reg11(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"1100" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 12
slv_reg12(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"1101" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 13
slv_reg13(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"1110" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 14
slv_reg14(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"1111" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 15
slv_reg15(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when others =>
slv_reg0 <= slv_reg0;
slv_reg1 <= slv_reg1;
slv_reg2 <= slv_reg2;
slv_reg3 <= slv_reg3;
slv_reg4 <= slv_reg4;
slv_reg5 <= slv_reg5;
slv_reg6 <= slv_reg6;
slv_reg7 <= slv_reg7;
slv_reg8 <= slv_reg8;
slv_reg9 <= slv_reg9;
--slv_reg10 <= slv_reg10;
slv_reg11 <= slv_reg11;
slv_reg12 <= slv_reg12;
slv_reg13 <= slv_reg13;
slv_reg14 <= slv_reg14;
slv_reg15 <= slv_reg15;
end case;
end if;
end if;
end if;
end process;
------------------------------------------------------------------------------------
--
-- Title : Clock Divider
--
-- Description: The following process takes a 50 MHz clock and divides it down to a
-- 25 MHz clock signal by assigning the signals clk_out and clk_div
-- to the 2nd bit of the clk_counter vector. clk_div is used by
-- the Finite State Machine and clk_out is used by the DAC121S101 chips.
--
------------------------------------------------------------------------------------
clock_divide : process(S_GCLK)
begin
if rising_edge(S_GCLK) then
if S_GRESET = '1' then
clk_counter <= "0000000000000000000000000000";
else
clk_counter <= clk_counter + '1';
end if;
end if;
end process;
clk_div <= clk_counter(0);
S_CLK_OUT <= clk_counter(0);
-----------------------------------------------------------------------------------
--
-- Title : counter
--
-- Description: This is the process were the teporary registers will be loaded and
-- shifted.When the enParalelLoad signal is generated inside the state
-- the temp1 and temp2 registers will be loaded with the 8 bits of control
-- concatenated with the 8 bits of data. When the enShiftCounter is
-- activated, the 16-bits of data inside the temporary registers will be
-- shifted. A 4-bit counter is used to keep shifting the data
-- inside temp1 and temp 2 for 16 clock cycles.
--
-----------------------------------------------------------------------------------
counter : process(clk_div, enParalelLoad, enShiftCounter)
begin
if rising_edge(clk_div) then
if enParalelLoad = '1' then
shiftCounter <= "0000";
temp1 <= control & DATA1;
temp2 <= control & DATA2;
elsif (enShiftCounter = '1') then
temp1 <= temp1(14 downto 0)&temp1(15);
temp2 <= temp2(14 downto 0)&temp2(15);
shiftCounter <= shiftCounter + '1';
end if;
end if;
end process;
S_D1 <= temp1(15);
S_D2 <= temp2(15);
--S_D2 <= S_GCLK;
DATA1 <= slv_reg1(11 downto 0);
DATA2 <= slv_reg2(11 downto 0);
---------------------------------------------------------------------------------
--
-- Title : Finite State Machine
--
-- Description: This 3 processes represent the FSM that contains three states.
-- First one is the Idle state in which the temporary registers are
-- assigned the updated value of the input "DATA1" and "DATA2".
-- The next state is the ShiftOut state which is the state where the
-- 16-bits of temporary registers are shifted out left from the MSB
-- to the two serial outputs, D1 and D2. Immediately following the
-- second state is the third state SyncData. This state drives the
-- output signal sync high for2 clock signals telling the DAC121S101
-- to latch the 16-bit data it just recieved in the previous state.
-- Notes: The data will change on the upper edge of the clock signal. Their
-- is also an asynchronous reset that will reset all signals to their
-- original state.
--
-----------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
--
-- Title : SYNC_PROC
--
-- Description: This is the process were the states are changed synchronously. At
-- reset the current state becomes Idle state.
--
-----------------------------------------------------------------------------------
SYNC_PROC: process (clk_div, S_GRESET)
begin
if rising_edge(clk_div) then
if (S_GRESET = '1') then
current_state <= Idle;
else
current_state <= next_state;
end if;
end if;
end process;
-----------------------------------------------------------------------------------
--
-- Title : OUTPUT_DECODE
--
-- Description: This is the process were the output signals are generated
-- unsynchronously based on the state only (Moore State Machine).
--
-----------------------------------------------------------------------------------
OUTPUT_DECODE: process (current_state)
begin
if current_state = Idle then
enShiftCounter <='0';
S_DONE <='1';
S_NSYNC <='1';
enParalelLoad <= '1';
elsif current_state = ShiftOut then
enShiftCounter <='1';
S_DONE <='0';
S_NSYNC <='0';
enParalelLoad <= '0';
else --if current_state = SyncData then
enShiftCounter <='0';
S_DONE <='0';
S_NSYNC <='1';
enParalelLoad <= '0';
end if;
end process;
START <= slv_reg0(0);
S_LEDS_OUT(0) <= START;
-----------------------------------------------------------------------------------
--
-- Title : NEXT_STATE_DECODE
--
-- Description: This is the process were the next state logic is generated
-- depending on the current state and the input signals.
--
-----------------------------------------------------------------------------------
NEXT_STATE_DECODE: process (current_state, START, shiftCounter)
begin
next_state <= current_state; --default is to stay in current state
case (current_state) is
when Idle =>
if START = '1' then
next_state <= ShiftOut;
end if;
when ShiftOut =>
if shiftCounter = x"F" then
next_state <= SyncData;
end if;
when SyncData =>
if START = '0' then
next_state <= Idle;
end if;
when others =>
next_state <= Idle;
end case;
end process;
-- Implement write response logic generation
-- The write response and response valid signals are asserted by the slave
-- when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.
-- This marks the acceptance of address and indicates the status of
-- write transaction.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_bvalid <= '0';
axi_bresp <= "00"; --need to work more on the responses
else
if (axi_awready = '1' and S_AXI_AWVALID = '1' and axi_wready = '1' and S_AXI_WVALID = '1' and axi_bvalid = '0' ) then
axi_bvalid <= '1';
axi_bresp <= "00";
elsif (S_AXI_BREADY = '1' and axi_bvalid = '1') then --check if bready is asserted while bvalid is high)
axi_bvalid <= '0'; -- (there is a possibility that bready is always asserted high)
end if;
end if;
end if;
end process;
-- Implement axi_arready generation
-- axi_arready is asserted for one S_AXI_ACLK clock cycle when
-- S_AXI_ARVALID is asserted. axi_awready is
-- de-asserted when reset (active low) is asserted.
-- The read address is also latched when S_AXI_ARVALID is
-- asserted. axi_araddr is reset to zero on reset assertion.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_arready <= '0';
axi_araddr <= (others => '1');
else
if (axi_arready = '0' and S_AXI_ARVALID = '1') then
-- indicates that the slave has acceped the valid read address
axi_arready <= '1';
-- Read Address latching
axi_araddr <= S_AXI_ARADDR;
else
axi_arready <= '0';
end if;
end if;
end if;
end process;
-- Implement axi_arvalid generation
-- axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both
-- S_AXI_ARVALID and axi_arready are asserted. The slave registers
-- data are available on the axi_rdata bus at this instance. The
-- assertion of axi_rvalid marks the validity of read data on the
-- bus and axi_rresp indicates the status of read transaction.axi_rvalid
-- is deasserted on reset (active low). axi_rresp and axi_rdata are
-- cleared to zero on reset (active low).
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_rvalid <= '0';
axi_rresp <= "00";
else
if (axi_arready = '1' and S_AXI_ARVALID = '1' and axi_rvalid = '0') then
-- Valid read data is available at the read data bus
axi_rvalid <= '1';
axi_rresp <= "00"; -- 'OKAY' response
elsif (axi_rvalid = '1' and S_AXI_RREADY = '1') then
-- Read data is accepted by the master
axi_rvalid <= '0';
end if;
end if;
end if;
end process;
-- Implement memory mapped register select and read logic generation
-- Slave register read enable is asserted when valid address is available
-- and the slave is ready to accept the read address.
slv_reg_rden <= axi_arready and S_AXI_ARVALID and (not axi_rvalid) ;
process (slv_reg0, slv_reg1, slv_reg2, slv_reg3, slv_reg4, slv_reg5, slv_reg6, slv_reg7, slv_reg8, slv_reg9, slv_reg10, slv_reg11, slv_reg12, slv_reg13, slv_reg14, slv_reg15, axi_araddr, S_AXI_ARESETN, slv_reg_rden)
variable loc_addr :std_logic_vector(OPT_MEM_ADDR_BITS downto 0);
begin
-- Address decoding for reading registers
loc_addr := axi_araddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB);
case loc_addr is
when b"0000" =>
reg_data_out <= slv_reg0;
when b"0001" =>
reg_data_out <= slv_reg1;
when b"0010" =>
reg_data_out <= slv_reg2;
when b"0011" =>
reg_data_out <= slv_reg3;
when b"0100" =>
reg_data_out <= slv_reg4;
when b"0101" =>
reg_data_out <= slv_reg5;
when b"0110" =>
reg_data_out <= slv_reg6;
when b"0111" =>
reg_data_out <= slv_reg7;
when b"1000" =>
reg_data_out <= slv_reg8;
when b"1001" =>
reg_data_out <= slv_reg9;
when b"1010" =>
reg_data_out <= slv_reg10;
when b"1011" =>
reg_data_out <= slv_reg11;
when b"1100" =>
reg_data_out <= slv_reg12;
when b"1101" =>
reg_data_out <= slv_reg13;
when b"1110" =>
reg_data_out <= slv_reg14;
when b"1111" =>
reg_data_out <= slv_reg15;
when others =>
reg_data_out <= (others => '0');
end case;
end process;
-- Output register or memory read data
process( S_AXI_ACLK ) is
begin
if (rising_edge (S_AXI_ACLK)) then
if ( S_AXI_ARESETN = '0' ) then
axi_rdata <= (others => '0');
else
if (slv_reg_rden = '1') then
-- When there is a valid read address (S_AXI_ARVALID) with
-- acceptance of read address by the slave (axi_arready),
-- output the read dada
-- Read address mux
axi_rdata <= reg_data_out; -- register read data
end if;
end if;
end if;
end process;
-- Add user logic here
-- User logic ends
end arch_imp;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment