-- The master requires a target slave base address.
-- The master will initiate read and write transactions on the slave with base address specified here as a parameter.
C_M_TARGET_SLAVE_BASE_ADDR : std_logic_vector := x"40000000";
- -- Width of M_AXI address bus.
+ -- Width of M_AXI address bus.
-- The master generates the read and write addresses of width specified as C_M_AXI_ADDR_WIDTH.
C_M_AXI_ADDR_WIDTH : integer := 32;
- -- Width of M_AXI data bus.
+ -- Width of M_AXI data bus.
-- The master issues write data and accept read data where the width of the data bus is C_M_AXI_DATA_WIDTH
C_M_AXI_DATA_WIDTH : integer := 32;
- -- Transaction number is the number of write
+ -- Transaction number is the number of write
-- and read transactions the master will perform as a part of this example memory test.
- C_M_TRANSACTIONS_NUM : integer := 4
+ C_M_TRANSACTIONS_NUM : integer := 1
);
port (
-- Users to add ports here
+ pwm_state_i : in std_logic_vector(1 downto 0);
+ pwm_enabled_i : in std_logic;
+ pwm_wr_addr : in std_logic_vector(C_M_AXI_DATA_WIDTH-1 downto 0);
+ pwm_wr0 : in std_logic_vector(C_M_AXI_DATA_WIDTH-1 downto 0);
+ pwm_wr1 : in std_logic_vector(C_M_AXI_DATA_WIDTH-1 downto 0);
+ pwm_wr2 : in std_logic_vector(C_M_AXI_DATA_WIDTH-1 downto 0);
-- User ports ends
-- Do not modify the ports beyond this line
-- Initiate AXI transactions
- INIT_AXI_TXN : in std_logic;
+ -- INIT_AXI_TXN : in std_logic;
-- Asserts when ERROR is detected
ERROR : out std_logic;
-- Asserts when AXI transactions is complete
-- This signal indicates the privilege and security level of the transaction,
-- and whether the transaction is a data access or an instruction access.
M_AXI_AWPROT : out std_logic_vector(2 downto 0);
- -- Write address valid.
+ -- Write address valid.
-- This signal indicates that the master signaling valid write address and control information.
M_AXI_AWVALID : out std_logic;
- -- Write address ready.
+ -- Write address ready.
-- This signal indicates that the slave is ready to accept an address and associated control signals.
M_AXI_AWREADY : in std_logic;
-- Master Interface Write Data Channel ports. Write data (issued by master)
M_AXI_WDATA : out std_logic_vector(C_M_AXI_DATA_WIDTH-1 downto 0);
- -- Write strobes.
+ -- 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.
M_AXI_WSTRB : out std_logic_vector(C_M_AXI_DATA_WIDTH/8-1 downto 0);
M_AXI_WVALID : out std_logic;
-- Write ready. This signal indicates that the slave can accept the write data.
M_AXI_WREADY : in std_logic;
- -- Master Interface Write Response Channel ports.
+ -- Master Interface Write Response Channel ports.
-- This signal indicates the status of the write transaction.
M_AXI_BRESP : in std_logic_vector(1 downto 0);
- -- Write response valid.
+ -- Write response valid.
-- This signal indicates that the channel is signaling a valid write response
M_AXI_BVALID : in std_logic;
-- Response ready. This signal indicates that the master can accept a write response.
M_AXI_BREADY : out std_logic;
-- Master Interface Read Address Channel ports. Read address (issued by master)
M_AXI_ARADDR : out std_logic_vector(C_M_AXI_ADDR_WIDTH-1 downto 0);
- -- Protection type.
- -- This signal indicates the privilege and security level of the transaction,
+ -- 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.
M_AXI_ARPROT : out std_logic_vector(2 downto 0);
- -- Read address valid.
+ -- Read address valid.
-- This signal indicates that the channel is signaling valid read address and control information.
M_AXI_ARVALID : out std_logic;
- -- Read address ready.
+ -- Read address ready.
-- This signal indicates that the slave is ready to accept an address and associated control signals.
M_AXI_ARREADY : in std_logic;
-- Master Interface Read Data Channel ports. Read data (issued by slave)
-- function called clogb2 that returns an integer which has the
-- value of the ceiling of the log base 2
- function clogb2 (bit_depth : integer) return integer is
- variable depth : integer := bit_depth;
- variable count : integer := 1;
- begin
+ function clogb2 (bit_depth : integer) return integer is
+ variable depth : integer := bit_depth;
+ variable count : integer := 1;
+ begin
for clogb2 in 1 to bit_depth loop -- Works for up to 32 bit integers
- if (bit_depth <= 2) then
- count := 1;
- else
- if(depth <= 1) then
- count := count;
- else
- depth := depth / 2;
- count := count + 1;
- end if;
- end if;
- end loop;
- return(count);
- end;
+ if (bit_depth <= 2) then
+ count := 1;
+ else
+ if(depth <= 1) then
+ count := count;
+ else
+ depth := depth / 2;
+ count := count + 1;
+ end if;
+ end if;
+ end loop;
+ return(count);
+ end;
-- Example user application signals
-- number of write or read transaction..
constant TRANS_NUM_BITS : integer := clogb2(C_M_TRANSACTIONS_NUM-1);
- -- Example State machine to initialize counter, initialize write transactions,
- -- initialize read transactions and comparison of read data with the
+ -- Example State machine to initialize counter, initialize write transactions,
+ -- initialize read transactions and comparison of read data with the
-- written data words.
type state is ( IDLE, -- This state initiates AXI4Lite transaction
-- after the state machine changes state to INIT_WRITE
-- when there is 0 to 1 transition on INIT_AXI_TXN
INIT_WRITE, -- This state initializes write transaction,
- -- once writes are done, the state machine
- -- changes state to INIT_READ
+ -- once writes are done, the state machine
+ -- changes state to INIT_READ
INIT_READ, -- This state initializes read transaction
- -- once reads are done, the state machine
- -- changes state to INIT_COMPARE
- INIT_COMPARE);-- This state issues the status of comparison
+ -- once reads are done, the state machine
+ -- changes state to INIT_COMPARE
+ INIT_COMPARE);-- This state issues the status of comparison
-- of the written data with the read data
- signal mst_exec_state : state ;
+ signal mst_exec_state : state ;
-- AXI4LITE signals
--write address valid
signal init_txn_edge : std_logic;
signal init_txn_pulse : std_logic;
+ signal INIT_AXI_TXN : std_logic := '0';
+
+ signal pwm_state_prev : std_logic_vector(1 downto 0) := "00";
+ signal pwm_state_inpr : std_logic_vector(1 downto 0) := "00";
begin
-- I/O Connections assignments
--Adding the offset address to the base addr of the slave
- M_AXI_AWADDR <= std_logic_vector (unsigned(C_M_TARGET_SLAVE_BASE_ADDR) + unsigned(axi_awaddr));
+ -- M_AXI_AWADDR <= std_logic_vector (unsigned(C_M_TARGET_SLAVE_BASE_ADDR) + unsigned(axi_awaddr));
+ M_AXI_AWADDR <= pwm_wr_addr;
--AXI 4 write data
- M_AXI_WDATA <= axi_wdata;
+ M_AXI_WDATA <= pwm_wr1 when (pwm_state_inpr = "01")
+ else pwm_wr2 when (pwm_state_inpr = "01")
+ else pwm_wr0;
+
M_AXI_AWPROT <= "000";
M_AXI_AWVALID <= axi_awvalid;
--Write Data(W)
TXN_DONE <= compare_done;
init_txn_pulse <= ( not init_txn_ff2) and init_txn_ff;
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ -- Initiates AXI transaction delay
+ if (M_AXI_ARESETN = '0' ) or (pwm_enabled_i = '0') then
+ INIT_AXI_TXN <= '0';
+ else
+ pwm_state_inpr <= pwm_state_inpr;
+ if (pwm_state_prev = pwm_state_i) or (mst_exec_state /= IDLE) then
+ INIT_AXI_TXN <= '0';
+ else
+ INIT_AXI_TXN <= '1';
+ pwm_state_inpr <= pwm_state_inpr;
+ end if;
+ end if;
+ end if;
+ end process;
--Generate a pulse to initiate AXI transaction.
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- -- Initiates AXI transaction delay
- if (M_AXI_ARESETN = '0' ) then
- init_txn_ff <= '0';
- init_txn_ff2 <= '0';
- else
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ -- Initiates AXI transaction delay
+ if (M_AXI_ARESETN = '0' ) then
+ init_txn_ff <= '0';
+ init_txn_ff2 <= '0';
+ else
init_txn_ff <= INIT_AXI_TXN;
- init_txn_ff2 <= init_txn_ff;
- end if;
- end if;
- end process;
+ init_txn_ff2 <= init_txn_ff;
+ end if;
+ end if;
+ end process;
----------------------
--Write Address Channel
----------------------
- -- The purpose of the write address channel is to request the address and
+ -- The purpose of the write address channel is to request the address and
-- command information for the entire transaction. It is a single beat
-- of information.
-- A data transfer is accepted by the slave when a master has
-- VALID data and the slave acknoledges it is also READY. While the master
- -- is allowed to generated multiple, back-to-back requests by not
+ -- is allowed to generated multiple, back-to-back requests by not
-- deasserting VALID, this design will add rest cycle for
-- simplicity.
-- Since only one outstanding transaction is issued by the user design,
-- there will not be a collision between a new request and an accepted
- -- request on the same clock cycle.
-
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- --Only VALID signals must be deasserted during reset per AXI spec
- --Consider inverting then registering active-low reset for higher fmax
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
- axi_awvalid <= '0';
- else
- --Signal a new address/data command is available by user logic
- if (start_single_write = '1') then
- axi_awvalid <= '1';
- elsif (M_AXI_AWREADY = '1' and axi_awvalid = '1') then
+ -- request on the same clock cycle.
+
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ --Only VALID signals must be deasserted during reset per AXI spec
+ --Consider inverting then registering active-low reset for higher fmax
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
+ axi_awvalid <= '0';
+ else
+ --Signal a new address/data command is available by user logic
+ if (start_single_write = '1') then
+ axi_awvalid <= '1';
+ elsif (M_AXI_AWREADY = '1' and axi_awvalid = '1') then
--Address accepted by interconnect/slave (issue of M_AXI_AWREADY by slave)
- axi_awvalid <= '0';
- end if;
- end if;
- end if;
- end process;
-
- -- start_single_write triggers a new write
- -- transaction. write_index is a counter to
- -- keep track with number of write transaction
- -- issued/initiated
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
- write_index <= (others => '0');
- elsif (start_single_write = '1') then
- -- Signals a new write address/ write data is
- -- available by user logic
- write_index <= std_logic_vector (unsigned(write_index) + 1);
- end if;
- end if;
- end process;
+ axi_awvalid <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
+
+ -- start_single_write triggers a new write
+ -- transaction. write_index is a counter to
+ -- keep track with number of write transaction
+ -- issued/initiated
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
+ write_index <= (others => '0');
+ elsif (start_single_write = '1') then
+ -- Signals a new write address/ write data is
+ -- available by user logic
+ write_index <= std_logic_vector (unsigned(write_index) + 1);
+ end if;
+ end if;
+ end process;
----------------------
----------------------
--The write data channel is for transfering the actual data.
- --The data generation is speific to the example design, and
+ --The data generation is speific to the example design, and
--so only the WVALID/WREADY handshake is shown here
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1' ) then
- axi_wvalid <= '0';
- else
- if (start_single_write = '1') then
- --Signal a new address/data command is available by user logic
- axi_wvalid <= '1';
- elsif (M_AXI_WREADY = '1' and axi_wvalid = '1') then
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1' ) then
+ axi_wvalid <= '0';
+ pwm_state_prev <= "00";
+ else
+ if (start_single_write = '1') then
+ --Signal a new address/data command is available by user logic
+ axi_wvalid <= '1';
+ elsif (M_AXI_WREADY = '1' and axi_wvalid = '1') then
--Data accepted by interconnect/slave (issue of M_AXI_WREADY by slave)
- axi_wvalid <= '0';
- end if;
- end if;
- end if;
- end process;
+ axi_wvalid <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
------------------------------
--While not necessary per spec, it is advisable to reset READY signals in
--case of differing reset latencies between master/slave.
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
- axi_bready <= '0';
- else
- if (M_AXI_BVALID = '1' and axi_bready = '0') then
- -- accept/acknowledge bresp with axi_bready by the master
- -- when M_AXI_BVALID is asserted by slave
- axi_bready <= '1';
- elsif (axi_bready = '1') then
- -- deassert after one clock cycle
- axi_bready <= '0';
- end if;
- end if;
- end if;
- end process;
- --Flag write errors
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
+ axi_bready <= '0';
+ else
+ if (M_AXI_BVALID = '1' and axi_bready = '0') then
+ -- accept/acknowledge bresp with axi_bready by the master
+ -- when M_AXI_BVALID is asserted by slave
+ axi_bready <= '1';
+ elsif (axi_bready = '1') then
+ -- deassert after one clock cycle
+ axi_bready <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
+ --Flag write errors
write_resp_error <= (axi_bready and M_AXI_BVALID and M_AXI_BRESP(1));
--start_single_read triggers a new read transaction. read_index is a counter to
--keep track with number of read transaction issued/initiated
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
- read_index <= (others => '0');
- else
- if (start_single_read = '1') then
- -- Signals a new read address is
- -- available by user logic
- read_index <= std_logic_vector (unsigned(read_index) + 1);
- end if;
- end if;
- end if;
- end process;
-
- -- A new axi_arvalid is asserted when there is a valid read address
- -- available by the master. start_single_read triggers a new read
- -- transaction
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
- axi_arvalid <= '0';
- else
- if (start_single_read = '1') then
- --Signal a new read address command is available by user logic
- axi_arvalid <= '1';
- elsif (M_AXI_ARREADY = '1' and axi_arvalid = '1') then
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
+ read_index <= (others => '0');
+ else
+ if (start_single_read = '1') then
+ -- Signals a new read address is
+ -- available by user logic
+ read_index <= std_logic_vector (unsigned(read_index) + 1);
+ end if;
+ end if;
+ end if;
+ end process;
+
+ -- A new axi_arvalid is asserted when there is a valid read address
+ -- available by the master. start_single_read triggers a new read
+ -- transaction
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
+ axi_arvalid <= '0';
+ else
+ if (start_single_read = '1') then
+ --Signal a new read address command is available by user logic
+ axi_arvalid <= '1';
+ elsif (M_AXI_ARREADY = '1' and axi_arvalid = '1') then
--RAddress accepted by interconnect/slave (issue of M_AXI_ARREADY by slave)
- axi_arvalid <= '0';
- end if;
- end if;
- end if;
- end process;
+ axi_arvalid <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
----------------------------------
--Read Data (and Response) Channel
----------------------------------
- --The Read Data channel returns the results of the read request
+ --The Read Data channel returns the results of the read request
--The master will accept the read data by asserting axi_rready
--when there is a valid read data available.
--While not necessary per spec, it is advisable to reset READY signals in
--case of differing reset latencies between master/slave.
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
- axi_rready <= '1';
- else
- if (M_AXI_RVALID = '1' and axi_rready = '0') then
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
+ axi_rready <= '1';
+ else
+ if (M_AXI_RVALID = '1' and axi_rready = '0') then
-- accept/acknowledge rdata/rresp with axi_rready by the master
- -- when M_AXI_RVALID is asserted by slave
- axi_rready <= '1';
- elsif (axi_rready = '1') then
- -- deassert after one clock cycle
- axi_rready <= '0';
- end if;
- end if;
- end if;
- end process;
-
- --Flag write errors
- read_resp_error <= (axi_rready and M_AXI_RVALID and M_AXI_RRESP(1));
+ -- when M_AXI_RVALID is asserted by slave
+ axi_rready <= '1';
+ elsif (axi_rready = '1') then
+ -- deassert after one clock cycle
+ axi_rready <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
+
+ --Flag write errors
+ read_resp_error <= (axi_rready and M_AXI_RVALID and M_AXI_RRESP(1));
----------------------------------
--match.
--Modify these as desired for different address patterns.
- -- Write Addresses
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
- axi_awaddr <= (others => '0');
- elsif (M_AXI_AWREADY = '1' and axi_awvalid = '1') then
- -- Signals a new write address/ write data is
- -- available by user logic
- axi_awaddr <= std_logic_vector (unsigned(axi_awaddr) + 4);
- end if;
- end if;
- end process;
-
- -- Read Addresses
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1' ) then
- axi_araddr <= (others => '0');
- elsif (M_AXI_ARREADY = '1' and axi_arvalid = '1') then
- -- Signals a new write address/ write data is
- -- available by user logic
- axi_araddr <= std_logic_vector (unsigned(axi_araddr) + 4);
- end if;
- end if;
- end process;
-
- -- Write data
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
- axi_wdata <= C_M_START_DATA_VALUE;
- elsif (M_AXI_WREADY = '1' and axi_wvalid = '1') then
- -- Signals a new write address/ write data is
- -- available by user logic
- axi_wdata <= std_logic_vector (unsigned(C_M_START_DATA_VALUE) + unsigned(write_index));
- end if;
- end if;
- end process;
-
-
- -- Expected read data
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1' ) then
- expected_rdata <= C_M_START_DATA_VALUE;
- elsif (M_AXI_RVALID = '1' and axi_rready = '1') then
- -- Signals a new write address/ write data is
- -- available by user logic
- expected_rdata <= std_logic_vector (unsigned(C_M_START_DATA_VALUE) + unsigned(read_index));
- end if;
- end if;
- end process;
- --implement master command interface state machine
- MASTER_EXECUTION_PROC:process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' ) then
- -- reset condition
- -- All the signals are ed default values under reset condition
- mst_exec_state <= IDLE;
- start_single_write <= '0';
- write_issued <= '0';
- start_single_read <= '0';
- read_issued <= '0';
- compare_done <= '0';
- ERROR <= '0';
- else
- -- state transition
- case (mst_exec_state) is
-
- when IDLE =>
+ -- Write Addresses
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
+ axi_awaddr <= (others => '0');
+ elsif (M_AXI_AWREADY = '1' and axi_awvalid = '1') then
+ -- Signals a new write address/ write data is
+ -- available by user logic
+ axi_awaddr <= std_logic_vector (unsigned(axi_awaddr) + 4);
+ end if;
+ end if;
+ end process;
+
+ -- Read Addresses
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1' ) then
+ axi_araddr <= (others => '0');
+ elsif (M_AXI_ARREADY = '1' and axi_arvalid = '1') then
+ -- Signals a new write address/ write data is
+ -- available by user logic
+ axi_araddr <= std_logic_vector (unsigned(axi_araddr) + 4);
+ end if;
+ end if;
+ end process;
+
+ -- Write data
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
+ axi_wdata <= C_M_START_DATA_VALUE;
+ elsif (M_AXI_WREADY = '1' and axi_wvalid = '1') then
+ -- Signals a new write address/ write data is
+ -- available by user logic
+ axi_wdata <= std_logic_vector (unsigned(C_M_START_DATA_VALUE) + unsigned(write_index));
+ end if;
+ end if;
+ end process;
+
+
+ -- Expected read data
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1' ) then
+ expected_rdata <= C_M_START_DATA_VALUE;
+ elsif (M_AXI_RVALID = '1' and axi_rready = '1') then
+ -- Signals a new write address/ write data is
+ -- available by user logic
+ expected_rdata <= std_logic_vector (unsigned(C_M_START_DATA_VALUE) + unsigned(read_index));
+ end if;
+ end if;
+ end process;
+ --implement master command interface state machine
+ MASTER_EXECUTION_PROC:process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' ) then
+ -- reset condition
+ -- All the signals are ed default values under reset condition
+ mst_exec_state <= IDLE;
+ start_single_write <= '0';
+ write_issued <= '0';
+ start_single_read <= '0';
+ read_issued <= '0';
+ compare_done <= '0';
+ ERROR <= '0';
+ pwm_state_prev <= "00";
+ else
+ pwm_state_prev <= pwm_state_prev;
+ -- state transition
+ case (mst_exec_state) is
+
+ when IDLE =>
-- This state is responsible to initiate
- -- AXI transaction when init_txn_pulse is asserted
- if ( init_txn_pulse = '1') then
- mst_exec_state <= INIT_WRITE;
+ -- AXI transaction when init_txn_pulse is asserted
+ if ( init_txn_pulse = '1') then
+ mst_exec_state <= INIT_WRITE;
ERROR <= '0';
compare_done <= '0';
- else
- mst_exec_state <= IDLE;
- end if;
-
- when INIT_WRITE =>
- -- This state is responsible to issue start_single_write pulse to
- -- initiate a write transaction. Write transactions will be
- -- issued until last_write signal is asserted.
- -- write controller
- if (writes_done = '1') then
- mst_exec_state <= INIT_READ;
- else
- mst_exec_state <= INIT_WRITE;
-
- if (axi_awvalid = '0' and axi_wvalid = '0' and M_AXI_BVALID = '0' and
- last_write = '0' and start_single_write = '0' and write_issued = '0') then
- start_single_write <= '1';
- write_issued <= '1';
- elsif (axi_bready = '1') then
- write_issued <= '0';
- else
- start_single_write <= '0'; --Negate to generate a pulse
- end if;
- end if;
-
- when INIT_READ =>
- -- This state is responsible to issue start_single_read pulse to
- -- initiate a read transaction. Read transactions will be
- -- issued until last_read signal is asserted.
- -- read controller
- if (reads_done = '1') then
- mst_exec_state <= INIT_COMPARE;
- else
- mst_exec_state <= INIT_READ;
-
- if (axi_arvalid = '0' and M_AXI_RVALID = '0' and last_read = '0' and
- start_single_read = '0' and read_issued = '0') then
- start_single_read <= '1';
- read_issued <= '1';
- elsif (axi_rready = '1') then
- read_issued <= '0';
- else
- start_single_read <= '0'; --Negate to generate a pulse
- end if;
- end if;
-
- when INIT_COMPARE =>
- -- This state is responsible to issue the state of comparison
- -- of written data with the read data. If no error flags are set,
- -- compare_done signal will be asseted to indicate success.
- ERROR <= error_reg;
- mst_exec_state <= IDLE;
- compare_done <= '1';
-
- when others =>
- mst_exec_state <= IDLE;
- end case ;
- end if;
- end if;
- end process;
-
- --Terminal write count
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
- -- reset condition
- last_write <= '0';
- else
- --The last write should be associated with a write address ready response
+ else
+ mst_exec_state <= IDLE;
+ end if;
+
+ when INIT_WRITE =>
+ -- This state is responsible to issue start_single_write pulse to
+ -- initiate a write transaction. Write transactions will be
+ -- issued until last_write signal is asserted.
+ -- write controller
+ if (writes_done = '1') then
+ -- mst_exec_state <= INIT_READ;
+ mst_exec_state <= IDLE;
+ pwm_state_prev <= pwm_state_inpr;
+ else
+ mst_exec_state <= INIT_WRITE;
+
+ if (axi_awvalid = '0' and axi_wvalid = '0' and M_AXI_BVALID = '0' and
+ last_write = '0' and start_single_write = '0' and write_issued = '0') then
+ start_single_write <= '1';
+ write_issued <= '1';
+ elsif (axi_bready = '1') then
+ write_issued <= '0';
+ else
+ start_single_write <= '0'; --Negate to generate a pulse
+ end if;
+ end if;
+
+ when INIT_READ =>
+ -- This state is responsible to issue start_single_read pulse to
+ -- initiate a read transaction. Read transactions will be
+ -- issued until last_read signal is asserted.
+ -- read controller
+ if (reads_done = '1') then
+ mst_exec_state <= INIT_COMPARE;
+ else
+ mst_exec_state <= INIT_READ;
+
+ if (axi_arvalid = '0' and M_AXI_RVALID = '0' and last_read = '0' and
+ start_single_read = '0' and read_issued = '0') then
+ start_single_read <= '1';
+ read_issued <= '1';
+ elsif (axi_rready = '1') then
+ read_issued <= '0';
+ else
+ start_single_read <= '0'; --Negate to generate a pulse
+ end if;
+ end if;
+
+ when INIT_COMPARE =>
+ -- This state is responsible to issue the state of comparison
+ -- of written data with the read data. If no error flags are set,
+ -- compare_done signal will be asseted to indicate success.
+ ERROR <= error_reg;
+ mst_exec_state <= IDLE;
+ compare_done <= '1';
+
+ when others =>
+ mst_exec_state <= IDLE;
+ end case ;
+ end if;
+ end if;
+ end process;
+
+ --Terminal write count
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
+ -- reset condition
+ last_write <= '0';
+ else
+ --The last write should be associated with a write address ready response
if (write_index = STD_LOGIC_VECTOR(TO_UNSIGNED(C_M_TRANSACTIONS_NUM, TRANS_NUM_BITS+1)) and M_AXI_AWREADY = '1') then
- last_write <= '1';
- end if;
- end if;
- end if;
- end process;
-
- --/*
- -- Check for last write completion.
- --
- -- This logic is to qualify the last write count with the final write
- -- response. This demonstrates how to confirm that a write has been
- -- committed.
- -- */
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
- -- reset condition
- writes_done <= '0';
- else
- if (last_write = '1' and M_AXI_BVALID = '1' and axi_bready = '1') then
- --The writes_done should be associated with a bready response
- writes_done <= '1';
- end if;
- end if;
- end if;
- end process;
-
- --------------
- --Read example
- --------------
-
- --Terminal Read Count
-
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
- last_read <= '0';
- else
+ last_write <= '1';
+ end if;
+ end if;
+ end if;
+ end process;
+
+ --/*
+ -- Check for last write completion.
+ --
+ -- This logic is to qualify the last write count with the final write
+ -- response. This demonstrates how to confirm that a write has been
+ -- committed.
+ -- */
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
+ -- reset condition
+ writes_done <= '0';
+ else
+ if (last_write = '1' and M_AXI_BVALID = '1' and axi_bready = '1') then
+ --The writes_done should be associated with a bready response
+ writes_done <= '1';
+ end if;
+ end if;
+ end if;
+ end process;
+
+ --------------
+ --Read example
+ --------------
+
+ --Terminal Read Count
+
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
+ last_read <= '0';
+ else
if (read_index = STD_LOGIC_VECTOR(TO_UNSIGNED(C_M_TRANSACTIONS_NUM, TRANS_NUM_BITS+1)) and (M_AXI_ARREADY = '1') ) then
- --The last read should be associated with a read address ready response
- last_read <= '1';
- end if;
- end if;
- end if;
- end process;
-
-
- --/*
- -- Check for last read completion.
- --
- -- This logic is to qualify the last read count with the final read
- -- response/data.
- -- */
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
- reads_done <= '0';
- else
- if (last_read = '1' and M_AXI_RVALID = '1' and axi_rready = '1') then
- --The reads_done should be associated with a read ready response
- reads_done <= '1';
- end if;
- end if;
- end if;
- end process;
-
-
- ------------------------------/
- --Example design error register
- ------------------------------/
-
- --Data Comparison
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
- read_mismatch <= '0';
- else
- if ((M_AXI_RVALID = '1' and axi_rready = '1') and M_AXI_RDATA /= expected_rdata) then
- --The read data when available (on axi_rready) is compared with the expected data
- read_mismatch <= '1';
- end if;
- end if;
- end if;
- end process;
-
- -- Register and hold any data mismatches, or read/write interface errors
- process(M_AXI_ACLK)
- begin
- if (rising_edge (M_AXI_ACLK)) then
- if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
- error_reg <= '0';
- else
- if (read_mismatch = '1' or write_resp_error = '1' or read_resp_error = '1') then
- --Capture any error types
- error_reg <= '1';
- end if;
- end if;
- end if;
- end process;
+ --The last read should be associated with a read address ready response
+ last_read <= '1';
+ end if;
+ end if;
+ end if;
+ end process;
+
+
+ --/*
+ -- Check for last read completion.
+ --
+ -- This logic is to qualify the last read count with the final read
+ -- response/data.
+ -- */
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
+ reads_done <= '0';
+ else
+ if (last_read = '1' and M_AXI_RVALID = '1' and axi_rready = '1') then
+ --The reads_done should be associated with a read ready response
+ reads_done <= '1';
+ end if;
+ end if;
+ end if;
+ end process;
+
+
+ ------------------------------/
+ --Example design error register
+ ------------------------------/
+
+ --Data Comparison
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
+ read_mismatch <= '0';
+ else
+ if ((M_AXI_RVALID = '1' and axi_rready = '1') and M_AXI_RDATA /= expected_rdata) then
+ --The read data when available (on axi_rready) is compared with the expected data
+ read_mismatch <= '1';
+ end if;
+ end if;
+ end if;
+ end process;
+
+ -- Register and hold any data mismatches, or read/write interface errors
+ process(M_AXI_ACLK)
+ begin
+ if (rising_edge (M_AXI_ACLK)) then
+ if (M_AXI_ARESETN = '0' or init_txn_pulse = '1') then
+ error_reg <= '0';
+ else
+ if (read_mismatch = '1' or write_resp_error = '1' or read_resp_error = '1') then
+ --Capture any error types
+ error_reg <= '1';
+ end if;
+ end if;
+ end if;
+ end process;
-- Add user logic here