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