SURF  1.0
AxiLiteToDrp.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiLiteToDrp.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2016-02-10
5 -- Last update: 2016-02-17
6 -------------------------------------------------------------------------------
7 -- Description: AXI-Lite to Xilinx DRP Bridge
8 -------------------------------------------------------------------------------
9 -- This file is part of 'SLAC Firmware Standard Library'.
10 -- It is subject to the license terms in the LICENSE.txt file found in the
11 -- top-level directory of this distribution and at:
12 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
13 -- No part of 'SLAC Firmware Standard Library', including this file,
14 -- may be copied, modified, propagated, or distributed except according to
15 -- the terms contained in the LICENSE.txt file.
16 -------------------------------------------------------------------------------
17 
18 library ieee;
19 use ieee.std_logic_1164.all;
20 use ieee.std_logic_arith.all;
21 use ieee.std_logic_unsigned.all;
22 
23 use work.StdRtlPkg.all;
24 use work.AxiLitePkg.all;
25 
26 --! @see entity
27  --! @ingroup axi
28 entity AxiLiteToDrp is
29  generic (
30  TPD_G : time := 1 ns;
32  COMMON_CLK_G : boolean := false;
33  EN_ARBITRATION_G : boolean := false;
34  TIMEOUT_G : positive := 4096;
35  ADDR_WIDTH_G : positive range 1 to 32 := 16;
36  DATA_WIDTH_G : positive range 1 to 32 := 16);
37  port (
38  -- AXI-Lite Port
39  axilClk : in sl;
40  axilRst : in sl;
45  -- DRP Interface
46  drpClk : in sl;
47  drpRst : in sl;
48  drpGnt : in sl := '1'; -- Used if EN_ARBITRATION_G = true
49  drpReq : out sl; -- Used if EN_ARBITRATION_G = true
50  drpRdy : in sl;
51  drpEn : out sl;
52  drpWe : out sl;
53  drpUsrRst : out sl;
54  drpAddr : out slv(ADDR_WIDTH_G-1 downto 0);
55  drpDi : out slv(DATA_WIDTH_G-1 downto 0);
56  drpDo : in slv(DATA_WIDTH_G-1 downto 0));
57 end entity AxiLiteToDrp;
58 
59 architecture rtl of AxiLiteToDrp is
60 
61  type StateType is (
62  IDLE_S,
63  REQ_S,
64  ACK_S);
65 
66  type RegType is record
67  drpUsrRst : sl;
68  drpReq : sl;
69  drpEn : sl;
70  drpWe : sl;
71  drpAddr : slv(ADDR_WIDTH_G-1 downto 0);
72  drpDi : slv(DATA_WIDTH_G-1 downto 0);
73  timer : natural range 0 to TIMEOUT_G;
74  writeSlave : AxiLiteWriteSlaveType;
75  readSlave : AxiLiteReadSlaveType;
76  state : StateType;
77  end record;
78 
79  constant REG_INIT_C : RegType := (
80  drpUsrRst => '1',
81  drpReq => '0',
82  drpEn => '0',
83  drpWe => '0',
84  drpAddr => (others => '0'),
85  drpDi => (others => '0'),
86  timer => 0,
87  writeSlave => AXI_LITE_WRITE_SLAVE_INIT_C,
88  readSlave => AXI_LITE_READ_SLAVE_INIT_C,
89  state => IDLE_S);
90 
91  signal r : RegType := REG_INIT_C;
92  signal rin : RegType;
93 
94  signal readMaster : AxiLiteReadMasterType;
95  signal readSlave : AxiLiteReadSlaveType;
96  signal writeMaster : AxiLiteWriteMasterType;
97  signal writeSlave : AxiLiteWriteSlaveType;
98 
99  -- attribute dont_touch : string;
100  -- attribute dont_touch of r : signal is "true";
101 
102 begin
103 
104  GEN_ASYNC : if (COMMON_CLK_G = false) generate
105 
106  U_AxiLiteAsync : entity work.AxiLiteAsync
107  generic map (
108  TPD_G => TPD_G)
109  port map (
110  -- Slave Port
111  sAxiClk => axilClk,
112  sAxiClkRst => axilRst,
117  -- Master Port
118  mAxiClk => drpClk,
119  mAxiClkRst => drpRst,
120  mAxiReadMaster => readMaster,
121  mAxiReadSlave => readSlave,
122  mAxiWriteMaster => writeMaster,
123  mAxiWriteSlave => writeSlave);
124 
125  end generate;
126 
127  GEN_SYNC : if (COMMON_CLK_G = true) generate
128 
129  readMaster <= axilReadMaster;
130  axilReadSlave <= readSlave;
131  writeMaster <= axilWriteMaster;
132  axilWriteSlave <= writeSlave;
133 
134  end generate;
135 
136  comb : process (drpDo, drpGnt, drpRdy, drpRst, r, readMaster, writeMaster) is
137  variable v : RegType;
138  variable axiStatus : AxiLiteStatusType;
139  variable axiResp : slv(1 downto 0);
140  begin
141  -- Latch the current value
142  v := r;
143 
144  -- Reset the strobes
145  v.drpEn := '0';
146  v.drpWe := '0';
147  v.drpUsrRst := '0';
148 
149  -- Determine the transaction type
150  axiSlaveWaitTxn(writeMaster, readMaster, v.writeSlave, v.readSlave, axiStatus);
151 
152  -- State Machine
153  case (r.state) is
154  ----------------------------------------------------------------------
155  when IDLE_S =>
156  -- Reset the flags
157  v.drpReq := '0';
158  v.timer := 0;
159  -- Check for a write request
160  if (axiStatus.writeEnable = '1') then
161  -- Set the write address bus (32-bit access alignment)
162  v.drpAddr := writeMaster.awaddr(ADDR_WIDTH_G+1 downto 2);
163  -- Set the write data bus
164  v.drpDi := writeMaster.wdata(DATA_WIDTH_G-1 downto 0);
165  -- Check for DRP request/grant
166  if EN_ARBITRATION_G then
167  -- Next state
168  v.state := REQ_S;
169  else
170  -- Send a write command
171  v.drpEn := '1';
172  v.drpWe := '1';
173  -- Next state
174  v.state := ACK_S;
175  end if;
176  -- Check for a read request
177  elsif (axiStatus.readEnable = '1') then
178  -- Set the write address bus (32-bit access alignment)
179  v.drpAddr := readMaster.araddr(ADDR_WIDTH_G+1 downto 2);
180  -- Check for DRP request/grant
181  if EN_ARBITRATION_G then
182  -- Next state
183  v.state := REQ_S;
184  else
185  -- Send a read command
186  v.drpEn := '1';
187  v.drpWe := '0';
188  -- Next state
189  v.state := ACK_S;
190  end if;
191  end if;
192  ----------------------------------------------------------------------
193  when REQ_S =>
194  -- Request the DRP bus
195  v.drpReq := '1';
196  -- Check for DRP bus access granted
197  if (drpGnt = '1') or (r.timer = TIMEOUT_G) then
198  -- Check for a write request
199  if (axiStatus.writeEnable = '1') then
200  -- Check for non-timeout
201  if (drpGnt = '1') then
202  -- Reset the timer
203  v.timer := 0;
204  -- Send a write command
205  v.drpEn := '1';
206  v.drpWe := '1';
207  end if;
208  -- Next state
209  v.state := ACK_S;
210  -- Check for a read request
211  elsif (axiStatus.readEnable = '1') then
212  -- Check for non-timeout
213  if (drpGnt = '1') then
214  -- Reset the timer
215  v.timer := 0;
216  -- Send a read command
217  v.drpEn := '1';
218  v.drpWe := '0';
219  end if;
220  -- Next state
221  v.state := ACK_S;
222  else
223  -- Next state
224  v.state := IDLE_S;
225  end if;
226  else
227  -- Increment the timer
228  v.timer := r.timer + 1;
229  end if;
230  ----------------------------------------------------------------------
231  when ACK_S =>
232  -- Check for DRP acknowledgement of command
233  if (drpRdy = '1') or (r.timer = TIMEOUT_G) then
234  -- Check for non-timeout
235  if (drpRdy = '1') then
236  -- Return good transaction
237  axiResp := AXI_RESP_OK_C;
238  else
239  -- Return good transaction
240  axiResp := AXI_ERROR_RESP_G;
241  -- Attempt to re-initialize the DRP interface
242  v.drpUsrRst := '1';
243  end if;
244  -- Check for a write request
245  if (axiStatus.writeEnable = '1') then
246  -- Send AXI-Lite response
247  axiSlaveWriteResponse(v.writeSlave, axiResp);
248  -- Check for a read request
249  elsif (axiStatus.readEnable = '1') then
250  -- Set the read bus
251  v.readSlave.rdata(DATA_WIDTH_G-1 downto 0) := drpDo;
252  -- Send AXI-Lite Response
253  axiSlaveReadResponse(v.readSlave, axiResp);
254  end if;
255  -- Next state
256  v.state := IDLE_S;
257  else
258  -- Increment the timer
259  v.timer := r.timer + 1;
260  end if;
261  ----------------------------------------------------------------------
262  end case;
263 
264  -- Synchronous Reset
265  if (drpRst = '1') then
266  v := REG_INIT_C;
267  end if;
268 
269  -- Register the variable for next clock cycle
270  rin <= v;
271 
272  -- Outputs
273  readSlave <= r.readSlave;
274  writeSlave <= r.writeSlave;
275  drpReq <= r.drpReq;
276  drpEn <= r.drpEn;
277  drpWe <= r.drpWe;
278  drpAddr <= r.drpAddr;
279  drpDi <= r.drpDi;
280  drpUsrRst <= r.drpUsrRst;
281 
282  end process comb;
283 
284  seq : process (drpClk) is
285  begin
286  if (rising_edge(drpClk)) then
287  r <= rin after TPD_G;
288  end if;
289  end process seq;
290 
291 end architecture rtl;
ADDR_WIDTH_Gpositive range 1 to 32:= 16
out drpUsrRstsl
out drpAddrslv( ADDR_WIDTH_G- 1 downto 0)
AxiLiteWriteMasterType
Definition: AxiLitePkg.vhd:111
in drpGntsl := '1'
std_logic sl
Definition: StdRtlPkg.vhd:28
EN_ARBITRATION_Gboolean := false
DATA_WIDTH_Gpositive range 1 to 32:= 16
out axilReadSlaveAxiLiteReadSlaveType
in drpDoslv( DATA_WIDTH_G- 1 downto 0)
COMMON_CLK_Gboolean := false
slv( 31 downto 0) rdata
Definition: AxiLitePkg.vhd:89
out mAxiReadMasterAxiLiteReadMasterType
in mAxiWriteSlaveAxiLiteWriteSlaveType
out sAxiWriteSlaveAxiLiteWriteSlaveType
slv( 31 downto 0) wdata
Definition: AxiLitePkg.vhd:117
out axilWriteSlaveAxiLiteWriteSlaveType
AxiLiteStatusType axiStatus
Definition: AxiLitePkg.vhd:183
in sAxiReadMasterAxiLiteReadMasterType
in sAxiWriteMasterAxiLiteWriteMasterType
slv( 1 downto 0) := "11" AXI_RESP_DECERR_C
Definition: AxiLitePkg.vhd:49
in axilReadMasterAxiLiteReadMasterType
AxiLiteReadMasterType
Definition: AxiLitePkg.vhd:59
slv( 31 downto 0) awaddr
Definition: AxiLitePkg.vhd:113
TIMEOUT_Gpositive := 4096
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:95
out sAxiReadSlaveAxiLiteReadSlaveType
AxiLiteReadSlaveType
Definition: AxiLitePkg.vhd:85
in axilWriteMasterAxiLiteWriteMasterType
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_DECERR_C
TPD_Gtime := 1 ns
in mAxiReadSlaveAxiLiteReadSlaveType
in mAxiClkRstsl
slv( 1 downto 0) := "00" AXI_RESP_OK_C
Definition: AxiLitePkg.vhd:31
slv( 31 downto 0) araddr
Definition: AxiLitePkg.vhd:61
TPD_Gtime := 1 ns
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:156
out mAxiWriteMasterAxiLiteWriteMasterType
in sAxiClkRstsl
out drpDislv( DATA_WIDTH_G- 1 downto 0)
std_logic_vector slv
Definition: StdRtlPkg.vhd:29