1 ------------------------------------------------------------------------------- 2 -- File : UartAxiLiteMaster.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2016-06-09 5 -- Last update: 2016-06-29 6 ------------------------------------------------------------------------------- 7 -- Description: Ties together everything needed for a full duplex UART. 8 -- This includes Baud Rate Generator, Transmitter, Receiver and FIFOs. 9 ------------------------------------------------------------------------------- 10 -- This file is part of 'SLAC Firmware Standard Library'. 11 -- It is subject to the license terms in the LICENSE.txt file found in the 12 -- top-level directory of this distribution and at: 13 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 14 -- No part of 'SLAC Firmware Standard Library', including this file, 15 -- may be copied, modified, propagated, or distributed except according to 16 -- the terms contained in the LICENSE.txt file. 17 ------------------------------------------------------------------------------- 20 use ieee.std_logic_1164.
all;
21 use ieee.std_logic_arith.
all;
22 use ieee.std_logic_unsigned.
all;
30 --! @ingroup protocols_uart 42 -- Transmit parallel interface 51 end entity UartAxiLiteMaster;
66 type RegType is record 68 count : slv(2 downto 0);
71 uartTxData : slv(7 downto 0);
76 constant REG_INIT_C : RegType := ( 77 state => WAIT_START_S, 78 count => (others => '0'), 81 uartTxData => (others => '0'), 85 signal r : RegType := REG_INIT_C;
88 -- signal axilReq : AxiLiteMasterReqType; 91 signal uartRxData : slv(7 downto 0);
92 signal uartRxValid : sl;
93 -- signal uartRxReady : sl; 95 -- signal uartTxData : slv(7 downto 0); 96 -- signal uartTxValid : sl; 97 signal uartTxReady : sl;
99 -- translate a hex character 0-9 A-F into an slv 100 function hexToSlv (hex :
slv(
7 downto 0))
return slv is 103 char := 'val(conv_integer(hex));
105 return toSlv(int(char), 4);
109 function slvToHex (nibble :
slv(
3 downto 0))
return slv is 111 return toSlv('pos(chr(conv_integer(nibble))), 8);
116 ------------------------------------------------------------------------------------------------- 118 ------------------------------------------------------------------------------------------------- 129 wrData => r.uartTxData,
-- [in] 130 wrValid => r.uartTxValid,
-- [in] 131 wrReady => uartTxReady,
-- [out] 132 rdData => uartRxData,
-- [out] 133 rdValid => uartRxValid,
-- [out] 134 rdReady => r.uartRxReady,
-- [in] 144 req => r.axilReq,
-- [in] 145 ack => axilAck,
-- [out] 151 comb :
process (axilAck,
axilRst, r, uartRxData, uartRxValid, uartTxReady)
is 152 variable v : RegType;
154 procedure uartTx (byte :
in slv(
7 downto 0))
is 156 v.uartTxValid := '1';
157 v.uartTxData := byte;
158 end procedure uartTx;
160 procedure uartTx (char :
in )
is 162 uartTx(toSlv('pos(char), 8));
163 end procedure uartTx;
165 function isSpace (byte :
slv(
7 downto 0))
return is 167 return (byte = 'pos(' '));
168 end function isSpace;
170 function isEOL (byte :
slv(
7 downto 0))
return is 172 return (byte = 'pos(CR) or 180 -- "w|W ADDRHEX DATAHEX0 [DATAHEX1] [DATAHEX2]...\r|\n" 181 -- Writes echo'd back with resp code 182 -- "r|R ADDRHEX [NUMREADSHEX] \r|\n" 183 -- Resp: "r|R ADDRHEX DATAHEX0 [DATAHEX1] [DATAHEX2]...\r|\n" 184 -- Blank lines ignored 185 -- Extra words ignored. 187 -- Auto clear uartTxValid upton uartTxReady 188 if (uartTxReady = '1') then 189 v.uartTxValid := '0';
194 -- Any characters before 'r' or 'w' are thrown out 195 if (uartRxValid = '1') then 196 if (uartRxData = toSlv('pos('w'), 8) or 197 uartRxData = toSlv('pos('W'), 8)) then 199 v.axilReq.rnw := '0';
201 v.state := SPACE_ADDR_S;
202 elsif (uartRxData = toSlv('pos('r'), 8) or 203 uartRxData = toSlv('pos('R'), 8)) then 205 v.axilReq.rnw := '1';
207 v.state := SPACE_ADDR_S;
212 -- Need to check for the space after opcode 213 if (uartRxValid = '1') then 215 v.state := ADDR_SPACE_S;
216 v.axilReq.address := r.axilReq.address(27 downto 0) & hexToSlv(uartRxData);
218 -- Ignore character if its a space 219 if (isSpace(uartRxData)) then 223 -- Go back to start if EOL 224 if (isEOL(uartRxData)) then 225 v.state := WAIT_START_S;
231 if (uartRxValid = '1') then 233 v.axilReq.address := r.axilReq.address(27 downto 0) & hexToSlv(uartRxData);
235 -- Space indicates end of addr word 236 if (isSpace(uartRxData)) then 238 if (r.axilReq.rnw = '0') then 239 v.state := WR_DATA_S;
241 v.state := WAIT_EOL_S;
245 -- Go back to start if EOL and write op 246 -- Else do the read op 247 if (isEOL(uartRxData)) then 248 if (r.axilReq.rnw = '0') then 249 v.state := WAIT_START_S;
253 v.state := AXIL_TXN_S;
260 if (uartRxValid = '1') then 262 v.axilReq.wrData := r.axilReq.wrData(27 downto 0) & hexToSlv(uartRxData);
264 -- Space or EOL indicates end of wrData word 265 -- If space need to wait for EOL 266 if (isSpace(uartRxData)) then 268 v.state := WAIT_EOL_S;
271 -- If EOL can issue AXIL txn 272 if (isEOL(uartRxData)) then 275 v.state := AXIL_TXN_S;
280 -- Issue AXIL TXN once EOL seen 281 -- Any other charachters are echo'd but otherwise ignored 282 if (uartRxValid = '1') then 284 if (isEOL(uartRxData)) then 286 v.state := AXIL_TXN_S;
291 -- Transmit a space on first cycle of this state 292 if (r.axilReq.request = '0' and r.axilReq.rnw = '0') then 296 -- Assert request and wait for response 298 if (axilAck.done = '1') then 300 -- Done if write op, else transmit the read data 301 if (r.axilReq.rnw = '0') then 306 v.state := RD_DATA_S;
312 v.count := r.count + 1;
313 uartTx(slvToHex(r.rdData(31 downto 28)));
315 if (r.count = 7) then 316 v.state := RD_DATA_SPACE_S;
320 when RD_DATA_SPACE_S => 325 -- Send resp code first cycle of this state 326 if (r.axilReq.request = '1') then 327 -- Send the response code 328 uartTx(slvToHex(resize(axilAck.resp, 4)));
331 -- Release request and wait for done to fall 332 -- Send closing CR when it does 334 if (axilAck.done = '0') then 336 v.state := WAIT_START_S;
351 r <= rin after TPD_G;
356 end architecture rtl;
AxiLiteMasterReqType :=(request => '0',rnw => '1',address =>( others => '0'),wrData =>( others => '0')) AXI_LITE_MASTER_REQ_INIT_C
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 5
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 4
out mAxilReadMasterAxiLiteReadMasterType
out axilWriteMasterAxiLiteWriteMasterType
out axilReadMasterAxiLiteReadMasterType
in axilWriteSlaveAxiLiteWriteSlaveType
in reqAxiLiteMasterReqType
out ackAxiLiteMasterAckType
in wrDataslv( 7 downto 0)
in mAxilWriteSlaveAxiLiteWriteSlaveType
AXIL_CLK_FREQ_Greal := 125.0e6
out rdDataslv( 7 downto 0)
FIFO_BRAM_EN_Gboolean := false
BAUD_RATE_Ginteger := 115200
in mAxilReadSlaveAxiLiteReadSlaveType
FIFO_BRAM_EN_Gboolean := false
in axilReadSlaveAxiLiteReadSlaveType
CLK_FREQ_Greal := 125.0e6
slv( 31 downto 0) address
out mAxilWriteMasterAxiLiteWriteMasterType
BAUD_RATE_Ginteger := 115200