AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
transactor_if.vhd
1 -- Interface between transactor and packet buffers
2 --
3 -- This module knows nothing about the ipbus transaction protocol
4 --
5 -- Dave Newbold, October 2012
6 
7 library ieee;
8 use ieee.std_logic_1164.all;
9 use ieee.numeric_std.all;
10 use work.ipbus_trans_decl.all;
11 
12 entity transactor_if is
13  port(
14  clk: in std_logic;
15  rst: in std_logic;
16  trans_in: in ipbus_trans_in;
17  trans_out: out ipbus_trans_out;
18  ipb_req: out std_logic; -- Bus request
19  ipb_grant: in std_logic; -- Bus grant
20  rx_ready: out std_logic; -- New data is available
21  rx_next: in std_logic; -- Request for new data from transactor
22  rx_data: out std_logic_vector(31 downto 0); -- Packet data to transactor
23  tx_data: in std_logic_vector(31 downto 0); -- Packet data from transactor
24  tx_we: in std_logic; -- Transactor data valid
25  tx_hdr: in std_logic; -- Header word flag from transactor
26  tx_err: in std_logic;
27  pkt_rx: out std_logic;
28  pkt_tx: out std_logic
29  );
30 
31 end transactor_if;
32 
33 architecture rtl of transactor_if is
34 
35  type state_type is (ST_IDLE, ST_FIRST, ST_HDR, ST_PREBODY, ST_BODY, ST_DONE, ST_GAP);
36  signal state: state_type;
37 
38  signal dinit, dinit_d, dnext, dnext_d, dsel: std_logic;
39  signal rxd, rxf: std_logic_vector(31 downto 0);
40  signal raddr, waddr, haddr, waddrh: unsigned(addr_width - 1 downto 0);
41  signal hlen, blen, rctr, wctr: unsigned(15 downto 0);
42  signal idata, rdata: std_logic_vector(31 downto 0);
43  signal first, start, start_d: std_logic;
44 
45 
46 begin
47 
48  process(clk) -- Fall-through RAM
49  begin
50  if rising_edge(clk) then
51 
52  if dinit = '1' then
53  raddr <= (others => '0');
54  elsif dnext = '1' or dinit_d = '1' then
55  raddr <= raddr + 1;
56  end if;
57 
58  dinit_d <= dinit;
59  dnext_d <= dnext;
60  dsel <= dnext and dnext_d;
61 
62  if dinit = '1' or dinit_d = '1' or dnext = '1' or dnext_d = '1' then
63  rxf <= trans_in.rdata;
64  end if;
65 
66  end if;
67  end process;
68 
69  trans_out.raddr <= std_logic_vector(raddr) when dinit = '0' else (others => '0');
70  rxd <= rxf when dsel = '0' else trans_in.rdata;
71 
72  process(clk)
73  begin
74  if rising_edge(clk) then
75 
76  if rst = '1' then
77  state <= ST_IDLE;
78  else
79  case state is
80 
81  when ST_IDLE => -- Starting state
82  if start = '1' and start_d = '1' then
83  state <= ST_FIRST;
84  end if;
85 
86  when ST_FIRST => -- Get packet length
87  if rxd(31 downto 16) = X"0000" then
88  if rxd(15 downto 0) = X"0000" then
89  state <= ST_DONE;
90  else
91  state <= ST_PREBODY;
92  end if;
93  else
94  state <= ST_HDR;
95  end if;
96 
97  when ST_HDR => -- Transfer packet info
98  if rctr = hlen then
99  if blen = X"0000" then
100  state <= ST_DONE;
101  else
102  state <= ST_PREBODY;
103  end if;
104  end if;
105 
106  when ST_PREBODY =>
107  if ipb_grant = '1' then
108  state <= ST_BODY;
109  end if;
110 
111  when ST_BODY => -- Transfer body
112  if (rctr > blen and tx_hdr = '1') or tx_err = '1' then
113  state <= ST_DONE;
114  end if;
115 
116  when ST_DONE => -- Write buffer header
117  state <= ST_GAP;
118 
119  when ST_GAP =>
120  state <= ST_IDLE;
121 
122  end case;
123  end if;
124 
125  end if;
126  end process;
127 
128  start <= trans_in.pkt_rdy and not trans_in.busy;
129  dinit <= not start;
130  dnext <= '1' when state = ST_FIRST or state = ST_HDR or (state = ST_BODY and rx_next = '1') else '0';
131 
132  process(clk)
133  begin
134  if rising_edge(clk) then
135 
136  start_d <= start;
137 
138  if state = ST_IDLE and start = '1' then
139  hlen <= unsigned(rxd(31 downto 16));
140  blen <= unsigned(rxd(15 downto 0));
141  end if;
142 
143  if state = ST_HDR or (state = ST_BODY and tx_we = '1') then
144  waddr <= waddr + 1;
145  elsif state = ST_DONE or rst = '1' then
146  waddr <= to_unsigned(1, addr_width);
147  end if;
148 
149  if state = ST_IDLE or state = ST_PREBODY then
150  rctr <= X"0001";
151  elsif state = ST_HDR or (state = ST_BODY and rx_next = '1') then
152  rctr <= rctr + 1;
153  end if;
154 
155  if state = ST_PREBODY then
156  wctr <= X"0000";
157  elsif state = ST_BODY and tx_we = '1' and first = '0' then
158  wctr <= wctr + 1;
159  end if;
160 
161  if tx_hdr = '1' then
162  haddr <= waddr;
163  end if;
164 
165  if state = ST_PREBODY then
166  first <= '1';
167  elsif tx_we = '1' then
168  first <= '0';
169  end if;
170 
171  end if;
172  end process;
173 
174  ipb_req <= '1' when state = ST_PREBODY or state = ST_BODY else '0';
175 
176  rx_data <= rxd;
177  rx_ready <= '1' when state = ST_BODY and not (rctr > blen) else '0';
178 
179  idata <= std_logic_vector(hlen) & std_logic_vector(wctr) when state = ST_DONE
180  else rxd;
181 
182  waddrh <= (others => '0') when state = ST_DONE else waddr;
183 
184  trans_out.pkt_done <= '1' when state = ST_DONE else '0';
185  trans_out.we <= '1' when state = ST_HDR or (tx_we = '1' and first = '0') or state = ST_DONE else '0';
186  trans_out.waddr <= std_logic_vector(haddr) when (state = ST_BODY and tx_hdr = '1') else std_logic_vector(waddrh);
187  trans_out.wdata <= tx_data when state = ST_BODY else idata;
188 
189  pkt_rx <= '1' when state = ST_IDLE and start_d = '1' else '0';
190  pkt_tx <= '1' when state = ST_DONE else '0';
191 
192 end rtl;
193