SURF  1.0
SaciMultiPixel.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : PgpParallelSimModel.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 07/21/2016
5 -- Last update: 07/21/2016
6 -------------------------------------------------------------------------------
7 -- This file is part of 'SLAC Firmware Standard Library'.
8 -- It is subject to the license terms in the LICENSE.txt file found in the
9 -- top-level directory of this distribution and at:
10 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
11 -- No part of 'SLAC Firmware Standard Library', including this file,
12 -- may be copied, modified, propagated, or distributed except according to
13 -- the terms contained in the LICENSE.txt file.
14 -------------------------------------------------------------------------------
15 
16 library ieee;
17 use ieee.std_logic_1164.all;
18 use ieee.std_logic_arith.all;
19 use ieee.std_logic_unsigned.all;
20 
21 use work.StdRtlPkg.all;
22 use work.AxiLitePkg.all;
23 use work.SaciMultiPixelPkg.all;
24 
25 --! @see entity
26  --! @ingroup protocols_saci
27 entity SaciMultiPixel is
28  generic (
29  TPD_G : time := 1 ns;
30  MASK_REG_ADDR_G : slv(31 downto 0) := x"00000034";
31  SACI_BASE_ADDR_G : slv(31 downto 0) := x"02000000";
33  SACI_NUM_CHIPS_G : natural range 1 to 4 := 4
34  );
35  port (
36  axilClk : in sl;
37  axilRst : in sl;
38 
39  -- AXI lite slave port
44 
45  -- AXI lite master port
50  );
51 
52 end SaciMultiPixel;
53 
54 architecture rtl of SaciMultiPixel is
55 
56  type StateType is (S_IDLE_C, S_IS_ASIC_C, S_WRITE_C, S_WRITE_AXI_C,
57  S_READ_C, S_READ_AXI_C, S_DONE_OK_C, S_DONE_FAIL_C);
58 
59  type RegType is record
60  globalMultiPix : MultiPixelWriteType;
61  localMultiPix : MultiPixelWriteType;
62  asicMask : slv(3 downto 0);
63  writeCnt : slv(3 downto 0);
64  state : StateType;
65  timer : slv(23 downto 0);
66  timeout : sl;
67  fail : sl;
72  end record RegType;
73 
74  constant REG_INIT_C : RegType := (
75  globalMultiPix => MULTI_PIXEL_WRITE_INIT_C,
76  localMultiPix => MULTI_PIXEL_WRITE_INIT_C,
77  asicMask => (others=>'0'),
78  writeCnt => (others=>'0'),
79  state => S_IDLE_C,
80  timer => (others => '1'),
81  timeout => '0',
82  fail => '0',
87 
88  signal r : RegType := REG_INIT_C;
89  signal rin : RegType;
90 
91 begin
92 
93  assert (SACI_NUM_CHIPS_G = 4) report "Multi-pixel write supports only 4 ASIC configuration!" severity failure;
94 
96  variable v : RegType;
97  variable axiStatus : AxiLiteStatusType;
98  begin
99  v := r;
100 
101  v.sAxilReadSlave.rdata := (others => '0');
103 
104  if (axiStatus.writeEnable = '1' and r.globalMultiPix.req = '0') then
105  -- Pseudo SACI Commands (multi-pixel write)
106  if (sAxilWriteMaster.awaddr(7 downto 0) = x"00") then
107  v.globalMultiPix.row := sAxilWriteMaster.wdata(9 downto 0);
108  v.globalMultiPix.calRowFlag := sAxilWriteMaster.wdata(16);
109  v.globalMultiPix.calBotFlag := sAxilWriteMaster.wdata(17);
110  axiSlaveWriteResponse(v.sAxilWriteSlave, AXI_RESP_OK_C);
111  elsif (sAxilWriteMaster.awaddr(7 downto 0) = x"04") then
112  v.globalMultiPix.col := sAxilWriteMaster.wdata(9 downto 0);
113  axiSlaveWriteResponse(v.sAxilWriteSlave, AXI_RESP_OK_C);
114  elsif (sAxilWriteMaster.awaddr(7 downto 0) = x"08") then
115  v.globalMultiPix.data(0) := sAxilWriteMaster.wdata(15 downto 0);
116  axiSlaveWriteResponse(v.sAxilWriteSlave, AXI_RESP_OK_C);
117  elsif (sAxilWriteMaster.awaddr(7 downto 0) = x"0C") then
118  v.globalMultiPix.data(1) := sAxilWriteMaster.wdata(15 downto 0);
119  axiSlaveWriteResponse(v.sAxilWriteSlave, AXI_RESP_OK_C);
120  elsif (sAxilWriteMaster.awaddr(7 downto 0) = x"10") then
121  v.globalMultiPix.data(2) := sAxilWriteMaster.wdata(15 downto 0);
122  axiSlaveWriteResponse(v.sAxilWriteSlave, AXI_RESP_OK_C);
123  elsif (sAxilWriteMaster.awaddr(7 downto 0) = x"14") then
124  v.globalMultiPix.data(3) := sAxilWriteMaster.wdata(15 downto 0);
125  v.globalMultiPix.req := '1'; -- start the AxiL master
126  else
127  axiSlaveWriteResponse(v.sAxilWriteSlave, AXIL_ERR_RESP_G);
128  end if;
129  end if;
130 
131  if (axiStatus.readEnable = '1' and r.globalMultiPix.req = '0') then
132  if (sAxilReadMaster.araddr(7 downto 0) = x"00") then
133  v.sAxilReadSlave.rdata(9 downto 0) := r.globalMultiPix.row;
134  v.sAxilReadSlave.rdata(16) := r.globalMultiPix.calRowFlag;
135  v.sAxilReadSlave.rdata(17) := r.globalMultiPix.calBotFlag;
136  axiSlaveReadResponse(v.sAxilReadSlave, AXI_RESP_OK_C);
137  elsif (sAxilReadMaster.araddr(7 downto 0) = x"04") then
138  v.sAxilReadSlave.rdata(9 downto 0) := r.globalMultiPix.col;
139  axiSlaveReadResponse(v.sAxilReadSlave, AXI_RESP_OK_C);
140  elsif (sAxilReadMaster.araddr(7 downto 0) = x"08") then
141  v.sAxilReadSlave.rdata(15 downto 0) := r.globalMultiPix.data(0);
142  axiSlaveReadResponse(v.sAxilReadSlave, AXI_RESP_OK_C);
143  elsif (sAxilReadMaster.araddr(7 downto 0) = x"0C") then
144  v.sAxilReadSlave.rdata(15 downto 0) := r.globalMultiPix.data(1);
145  axiSlaveReadResponse(v.sAxilReadSlave, AXI_RESP_OK_C);
146  elsif (sAxilReadMaster.araddr(7 downto 0) = x"10") then
147  v.sAxilReadSlave.rdata(15 downto 0) := r.globalMultiPix.data(2);
148  axiSlaveReadResponse(v.sAxilReadSlave, AXI_RESP_OK_C);
149  elsif (sAxilReadMaster.araddr(7 downto 0) = x"14") then
150  v.sAxilReadSlave.rdata(15 downto 0) := r.globalMultiPix.data(3);
151  axiSlaveReadResponse(v.sAxilReadSlave, AXI_RESP_OK_C);
152  elsif (sAxilReadMaster.araddr(7 downto 0) = x"18") then
153  v.sAxilReadSlave.rdata(0) := r.fail;
154  v.sAxilReadSlave.rdata(1) := r.timeout;
155  axiSlaveReadResponse(v.sAxilReadSlave, AXI_RESP_OK_C);
156  else
157  axiSlaveReadResponse(v.sAxilReadSlave, AXIL_ERR_RESP_G);
158  end if;
159  end if;
160 
161 
162  -- State machine for SACI mediation
163  -- SACI is accessed via the AXI lite master bus
164  case(r.state) is
165  when S_IDLE_C =>
168  v.asicMask := (others => '0');
169  v.writeCnt := (others => '0');
170 
171  -- If we see a multi-pixel write request, handle it
172  if (r.globalMultiPix.req = '1') then
173  globalToLocalPixel(
174  r.globalMultiPix.row,
175  r.globalMultiPix.col,
176  r.globalMultiPix.calRowFlag,
177  r.globalMultiPix.calBotFlag,
178  r.globalMultiPix.data,
179  v.localMultiPix.asic,
180  v.localMultiPix.row,
181  v.localMultiPix.col,
182  v.localMultiPix.data);
183  v.timeout := '0';
184  v.fail := '0';
185  v.localMultiPix.bankFlag := "1110";
186  v.state := S_READ_C;
187  end if;
188 
189  -- Read the ASIC mask
190  when S_READ_C =>
192  v.mAxilReadMaster.arprot := (others => '0');
193  v.timer := (others => '1');
194 
195  -- Start AXI transaction
196  v.mAxilReadMaster.arvalid := '1';
197  v.mAxilReadMaster.rready := '1';
198  v.state := S_READ_AXI_C;
199 
200  -- Read AXI
201  when S_READ_AXI_C =>
202  v.timer := r.timer - 1;
203 
204  -- Clear control signals on ack
205  if mAxilReadSlave.arready = '1' then
206  v.mAxilReadMaster.arvalid := '0';
207  end if;
208  if mAxilReadSlave.rvalid = '1' then
209  v.mAxilReadMaster.rready := '0';
210  v.asicMask := mAxilReadSlave.rdata(3 downto 0);
211 
213  v.fail := '1';
214  end if;
215  end if;
216 
217  -- End transaction on timeout
218  if r.timer = 0 then
219  v.mAxilReadMaster.arvalid := '0';
220  v.mAxilReadMaster.rready := '0';
221  v.timeout := '1';
222  end if;
223 
224  -- Transaction is done
225  if v.mAxilReadMaster.arvalid = '0' and v.mAxilReadMaster.rready = '0' then
226  if v.fail = '1' or v.timeout = '1' then
227  v.state := S_DONE_FAIL_C;
228  else
229  v.state := S_IS_ASIC_C;
230  end if;
231  end if;
232 
233  -- Check if ASIC is enabled
234  when S_IS_ASIC_C =>
235  -- If the ASIC is not active, immediately drop the req and return
236  if (r.asicMask(conv_integer(r.localMultiPix.asic)) = '0') then
237  v.state := S_DONE_OK_C;
238  else
239  v.state := S_WRITE_C;
240  end if;
241 
242  -- Prepare Write Transactions
243  when S_WRITE_C =>
244  if r.writeCnt = 0 then
245  -- ASIC offset + CMD = 6, ADDR = 17
246  v.mAxilWriteMaster.awaddr := SACI_BASE_ADDR_G + asicBaseAddr(conv_integer(r.localMultiPix.asic)) + x"00018044";
247  -- DATA = ROW
248  v.mAxilWriteMaster.wdata := x"00000" & "000" & r.localMultiPix.row(8 downto 0);
249  elsif r.writeCnt = 1 then
250  -- ASIC offset + CMD = 6, ADDR = 19
251  v.mAxilWriteMaster.awaddr := SACI_BASE_ADDR_G + asicBaseAddr(conv_integer(r.localMultiPix.asic)) + x"0001804C";
252  -- DATA = Bank + Col
253  v.mAxilWriteMaster.wdata := x"00000" & "0" & r.localMultiPix.bankFlag & r.localMultiPix.col(6 downto 0);
254  elsif r.writeCnt = 2 then
255  -- ASIC offset + CMD = 5, ADDR = 0
256  v.mAxilWriteMaster.awaddr := SACI_BASE_ADDR_G + asicBaseAddr(conv_integer(r.localMultiPix.asic)) + x"00014000";
257  -- DATA = MT
258  v.mAxilWriteMaster.wdata := x"0000" & r.localMultiPix.data(0);
259  end if;
260 
261  v.mAxilWriteMaster.awprot := (others => '0');
262  v.mAxilWriteMaster.wstrb := (others => '1');
263  v.timer := (others => '1');
264 
265  v.mAxilWriteMaster.awvalid := '1';
266  v.mAxilWriteMaster.wvalid := '1';
267  v.mAxilWriteMaster.bready := '1';
268  v.state := S_WRITE_AXI_C;
269 
270  -- Write Transaction, AXI
271  when S_WRITE_AXI_C =>
272  v.timer := r.timer - 1;
273 
274  -- Clear control signals on ack
275  if mAxilWriteSlave.awready = '1' then
276  v.mAxilWriteMaster.awvalid := '0';
277  end if;
278  if mAxilWriteSlave.wready = '1' then
279  v.mAxilWriteMaster.wvalid := '0';
280  end if;
281  if mAxilWriteSlave.bvalid = '1' then
282  v.mAxilWriteMaster.bready := '0';
283 
285  v.fail := '1';
286  end if;
287  end if;
288 
289  -- End transaction on timeout
290  if r.timer = 0 then
291  v.mAxilWriteMaster.awvalid := '0';
292  v.mAxilWriteMaster.wvalid := '0';
293  v.mAxilWriteMaster.bready := '0';
294  v.timeout := '1';
295  end if;
296 
297  -- Transaction is done
298  if v.mAxilWriteMaster.awvalid = '0' and
299  v.mAxilWriteMaster.wvalid = '0' and
300  v.mAxilWriteMaster.bready = '0' then
301 
302  if v.fail = '1' or v.timeout = '1' then
303  v.state := S_DONE_FAIL_C;
304  elsif r.writeCnt >= 2 then
305  -- Done if this was the last bank
306  if r.localMultiPix.bankFlag = "0111" then
307  v.state := S_DONE_OK_C;
308  -- Otherwise, rotate the bank counter and pixel data
309  else
310  v.writeCnt := (others=>'0');
311  v.localMultiPix.bankFlag(3 downto 1) := r.localMultiPix.bankFlag(2 downto 0);
312  v.localMultiPix.bankFlag(0) := r.localMultiPix.bankFlag(3);
313  v.localMultiPix.data(2 downto 0) := r.localMultiPix.data(3 downto 1);
314  v.state := S_WRITE_C;
315  end if;
316  else
317  v.writeCnt := r.writeCnt + 1;
318  v.state := S_WRITE_C;
319  end if;
320 
321  end if;
322 
323  when S_DONE_OK_C =>
324  v.globalMultiPix.req := '0';
325  axiSlaveWriteResponse(v.sAxilWriteSlave, AXI_RESP_OK_C);
326  v.state := S_IDLE_C;
327 
328  when S_DONE_FAIL_C =>
329  v.globalMultiPix.req := '0';
330  axiSlaveWriteResponse(v.sAxilWriteSlave, AXIL_ERR_RESP_G);
331  v.state := S_IDLE_C;
332 
333  end case;
334 
335  if (axilRst = '1') then
336  v := REG_INIT_C;
337  end if;
338 
339  rin <= v;
340 
345 
346 
347  end process comb;
348 
349  seq : process (axilClk) is
350  begin
351  if (rising_edge(axilClk)) then
352  r <= rin after TPD_G;
353  end if;
354  end process seq;
355 
356 end rtl;
357 
slv( 2 downto 0) arprot
Definition: AxiLitePkg.vhd:62
out sAxilWriteSlaveAxiLiteWriteSlaveType
slv( 1 downto 0) rresp
Definition: AxiLitePkg.vhd:90
in sAxilWriteMasterAxiLiteWriteMasterType
TPD_Gtime := 1 ns
AxiLiteWriteMasterType
Definition: AxiLitePkg.vhd:111
std_logic sl
Definition: StdRtlPkg.vhd:28
SACI_BASE_ADDR_Gslv( 31 downto 0) := x"02000000"
slv( 31 downto 0) rdata
Definition: AxiLitePkg.vhd:89
AXIL_ERR_RESP_Gslv( 1 downto 0) := AXI_RESP_DECERR_C
slv( 1 downto 0) asic
out mAxilReadMasterAxiLiteReadMasterType
slv( 31 downto 0) wdata
Definition: AxiLitePkg.vhd:117
MASK_REG_ADDR_Gslv( 31 downto 0) := x"00000034"
AxiLiteStatusType axiStatus
Definition: AxiLitePkg.vhd:183
slv( 1 downto 0) := "11" AXI_RESP_DECERR_C
Definition: AxiLitePkg.vhd:49
MultiPixelWriteType :=(asic =>( others => '0'),row =>( others => '0'),col =>( others => '0'),data =>( others =>( others => '0')),bankFlag =>( others => '0'),calRowFlag => '0',calBotFlag => '0',req => '0') MULTI_PIXEL_WRITE_INIT_C
out sAxilReadSlaveAxiLiteReadSlaveType
SACI_NUM_CHIPS_Gnatural range 1 to 4:= 4
slv( 2 downto 0) awprot
Definition: AxiLitePkg.vhd:114
Slv16Array( 3 downto 0) data
AxiLiteReadMasterType
Definition: AxiLitePkg.vhd:59
out mAxilWriteMasterAxiLiteWriteMasterType
slv( 31 downto 0) awaddr
Definition: AxiLitePkg.vhd:113
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:95
slv( 1 downto 0) bresp
Definition: AxiLitePkg.vhd:150
AxiLiteReadMasterType :=(araddr =>( others => '0'),arprot =>( others => '0'),arvalid => '0',rready => '1') AXI_LITE_READ_MASTER_INIT_C
Definition: AxiLitePkg.vhd:69
AxiLiteReadSlaveType
Definition: AxiLitePkg.vhd:85
in mAxilWriteSlaveAxiLiteWriteSlaveType
AxiLiteWriteMasterType :=(awaddr =>( others => '0'),awprot =>( others => '0'),awvalid => '0',wdata =>( others => '0'),wstrb =>( others => '1'),wvalid => '0',bready => '1') AXI_LITE_WRITE_MASTER_INIT_C
Definition: AxiLitePkg.vhd:125
slv( 9 downto 0) row
slv( 1 downto 0) := "00" AXI_RESP_OK_C
Definition: AxiLitePkg.vhd:31
in mAxilReadSlaveAxiLiteReadSlaveType
in sAxilReadMasterAxiLiteReadMasterType
slv( 31 downto 0) araddr
Definition: AxiLitePkg.vhd:61
slv( 3 downto 0) wstrb
Definition: AxiLitePkg.vhd:118
slv( 3 downto 0) bankFlag
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:156
std_logic_vector slv
Definition: StdRtlPkg.vhd:29
slv( 9 downto 0) col