SURF  1.0
AxiAd5780Reg.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiAd5780Reg.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2014-04-18
5 -- Last update: 2016-09-20
6 -------------------------------------------------------------------------------
7 -- Description: AXI-Lite interface to AD5780 DAC IC
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_unsigned.all;
21 use ieee.std_logic_arith.all;
22 
23 use work.StdRtlPkg.all;
24 use work.AxiLitePkg.all;
25 use work.AxiAd5780Pkg.all;
26 
27 --! @see entity
28  --! @ingroup devices_AnalogDevices_ad5780
29 entity AxiAd5780Reg is
30  generic (
31  TPD_G : time := 1 ns;
32  STATUS_CNT_WIDTH_G : natural range 1 to 32 := 32;
33  USE_DSP48_G : string := "no"; -- "no" for no DSP48 implementation, "yes" to use DSP48 slices
34  AXI_CLK_FREQ_G : real := 200.0E+6; -- units of Hz
35  SPI_CLK_FREQ_G : real := 25.0E+6; -- units of Hz
37  port (
38  -- AXI-Lite Register Interface
43  -- Register Inputs/Outputs
45  config : out AxiAd5780ConfigType;
46  -- Global Signals
47  axiClk : in sl;
48  axiRst : in sl;
49  dacRst : out sl);
50 end AxiAd5780Reg;
51 
52 architecture rtl of AxiAd5780Reg is
53 
54  constant DOUBLE_SCK_FREQ_C : real := SPI_CLK_FREQ_G * 2.0E+0;
55  constant HALF_SCK_PERIOD_C : natural := (getTimeRatio(AXI_CLK_FREQ_G, DOUBLE_SCK_FREQ_C))-1;
56  constant HALF_SCK_PERIOD_INIT_C : slv(31 downto 0) := toSlv(HALF_SCK_PERIOD_C, 32);
57 
58  type RegType is record
59  dacRst : sl;
60  regOut : AxiAd5780ConfigType;
63  end record RegType;
64 
65  constant REG_INIT_C : RegType := (
66  '1',
70 
71  signal r : RegType := REG_INIT_C;
72  signal rin : RegType;
73 
76 
77  signal dacRefreshRate : slv(STATUS_CNT_WIDTH_G-1 downto 0);
78 
79 begin
80 
81  -------------------------------
82  -- Configuration Register
83  -------------------------------
84  comb : process (axiReadMaster, axiRst, axiWriteMaster, dacRefreshRate, r, regIn) is
85  variable v : RegType;
86  variable axiStatus : AxiLiteStatusType;
87  variable axiWriteResp : slv(1 downto 0);
88  variable axiReadResp : slv(1 downto 0);
89  begin
90  -- Latch the current value
91  v := r;
92 
93  -- Determine the transaction type
95 
96  -- Reset strobe signals
97  v.dacRst := '0';
98 
99  if (axiStatus.writeEnable = '1') then
100  -- Check for an out of 32 bit aligned address
101  axiWriteResp := ite(axiWriteMaster.awaddr(1 downto 0) = "00", AXI_RESP_OK_C, AXI_ERROR_RESP_G);
102  -- Decode address and perform write
103  case (axiWriteMaster.awaddr(9 downto 2)) is
104  when x"80" =>
105  v.regOut.debugMux := axiWriteMaster.wdata(0);
106  when x"90" =>
107  v.regOut.debugData := axiWriteMaster.wdata(17 downto 0);
108  when x"A0" =>
109  v.regOut.sdoDisable := axiWriteMaster.wdata(0);
110  v.dacRst := '1';
111  when x"A1" =>
112  v.regOut.binaryOffset := axiWriteMaster.wdata(0);
113  v.dacRst := '1';
114  when x"A2" =>
115  v.regOut.dacTriState := axiWriteMaster.wdata(0);
116  v.dacRst := '1';
117  when x"A3" =>
118  v.regOut.opGnd := axiWriteMaster.wdata(0);
119  v.dacRst := '1';
120  when x"A4" =>
121  v.regOut.rbuf := axiWriteMaster.wdata(0);
122  v.dacRst := '1';
123  when x"A5" =>
124  v.regOut.halfSckPeriod := axiWriteMaster.wdata;
125  v.dacRst := '1';
126  when x"FE" =>
127  v.dacRst := '1';
128  when others =>
129  axiWriteResp := AXI_ERROR_RESP_G;
130  end case;
131  -- Send AXI response
132  axiSlaveWriteResponse(v.axiWriteSlave, axiWriteResp);
133  end if;
134 
135  if (axiStatus.readEnable = '1') then
136  -- Check for an out of 32 bit aligned address
137  axiReadResp := ite(axiReadMaster.araddr(1 downto 0) = "00", AXI_RESP_OK_C, AXI_ERROR_RESP_G);
138  -- Decode address and assign read data
139  v.axiReadSlave.rdata := (others => '0');
140  case (axiReadMaster.araddr(9 downto 2)) is
141  when x"10" =>
142  v.axiReadSlave.rdata(STATUS_CNT_WIDTH_G-1 downto 0) := dacRefreshRate;
143  when x"30" =>
144  v.axiReadSlave.rdata(17 downto 0) := regIn.dacData;
145  when x"80" =>
146  v.axiReadSlave.rdata(0) := r.regOut.debugMux;
147  when x"90" =>
148  v.axiReadSlave.rdata(17 downto 0) := r.regOut.debugData;
149  when x"A0" =>
150  v.axiReadSlave.rdata(0) := r.regOut.sdoDisable;
151  when x"A1" =>
152  v.axiReadSlave.rdata(0) := r.regOut.binaryOffset;
153  when x"A2" =>
154  v.axiReadSlave.rdata(0) := r.regOut.dacTriState;
155  when x"A3" =>
156  v.axiReadSlave.rdata(0) := r.regOut.opGnd;
157  when x"A4" =>
158  v.axiReadSlave.rdata(0) := r.regOut.rbuf;
159  when x"A5" =>
160  v.axiReadSlave.rdata := r.regOut.halfSckPeriod;
161  when others =>
162  axiReadResp := AXI_ERROR_RESP_G;
163  end case;
164  -- Send Axi Response
165  axiSlaveReadResponse(v.axiReadSlave, axiReadResp);
166  end if;
167 
168  -- Synchronous Reset
169  if axiRst = '1' then
170  v := REG_INIT_C;
171  v.regOut.halfSckPeriod := HALF_SCK_PERIOD_INIT_C;
172  end if;
173 
174  -- Register the variable for next clock cycle
175  rin <= v;
176 
177  -- Outputs
180 
181  regOut <= r.regOut;
182 
183  dacRst <= r.dacRst;
184 
185  end process comb;
186 
187  seq : process (axiClk) is
188  begin
189  if rising_edge(axiClk) then
190  r <= rin after TPD_G;
191  end if;
192  end process seq;
193 
194  -------------------------------
195  -- Synchronization: Outputs
196  -------------------------------
197  config <= regOut;
198 
199  -------------------------------
200  -- Synchronization: Inputs
201  -------------------------------
202  regIn.dacData <= status.dacData;
203 
204  SyncTrigRate_Inst : entity work.SyncTrigRate
205  generic map (
206  TPD_G => TPD_G,
207  COMMON_CLK_G => true,
208  IN_POLARITY_G => '1',
210  REFRESH_RATE_G => 1.0E+0,
213  port map (
214  -- Trigger Input (locClk domain)
215  trigIn => status.dacUpdated,
216  -- Trigger Rate Output (locClk domain)
217  trigRateUpdated => open,
218  trigRateOut => dacRefreshRate,
219  -- Clocks
220  locClkEn => '1',
221  locClk => axiClk,
222  refClk => axiClk);
223 
224 end rtl;
IN_POLARITY_Gsl := '1'
out trigRateUpdatedsl
out axiReadSlaveAxiLiteReadSlaveType
AxiLiteWriteMasterType
Definition: AxiLitePkg.vhd:111
std_logic sl
Definition: StdRtlPkg.vhd:28
in axiWriteMasterAxiLiteWriteMasterType
slv( 31 downto 0) rdata
Definition: AxiLitePkg.vhd:89
out axiWriteSlaveAxiLiteWriteSlaveType
STATUS_CNT_WIDTH_Gnatural range 1 to 32:= 32
in statusAxiAd5780StatusType
slv( 31 downto 0) wdata
Definition: AxiLitePkg.vhd:117
AxiLiteStatusType axiStatus
Definition: AxiLitePkg.vhd:183
REFRESH_RATE_Greal := 1.0E+0
AxiAd5780StatusType :=( '0',( others => '0')) AXI_AD5780_STATUS_INIT_C
slv( 1 downto 0) := "10" AXI_RESP_SLVERR_C
Definition: AxiLitePkg.vhd:36
COMMON_CLK_Gboolean := false
slv( 17 downto 0) debugData
_library_ ieeeieee
in locClkEnsl := '1'
AxiLiteReadMasterType
Definition: AxiLitePkg.vhd:59
TPD_Gtime := 1 ns
slv( 31 downto 0) awaddr
Definition: AxiLitePkg.vhd:113
slv( 17 downto 0) dacData
AxiAd5780ConfigType :=(( others => '1'), '1', '0', '0', '0', '1', '0',( others => '0')) AXI_AD5780_CONFIG_INIT_C
CNT_WIDTH_Gpositive := 32
SPI_CLK_FREQ_Greal := 25.0E+6
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:95
slv( 31 downto 0) halfSckPeriod
TPD_Gtime := 1 ns
USE_DSP48_Gstring := "no"
AxiLiteReadSlaveType
Definition: AxiLitePkg.vhd:85
REF_CLK_FREQ_Greal := 200.0E+6
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_SLVERR_C
slv( 1 downto 0) := "00" AXI_RESP_OK_C
Definition: AxiLitePkg.vhd:31
slv( 31 downto 0) araddr
Definition: AxiLitePkg.vhd:61
AXI_CLK_FREQ_Greal := 200.0E+6
USE_DSP48_Gstring := "no"
out trigRateOutslv( CNT_WIDTH_G- 1 downto 0)
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
in axiReadMasterAxiLiteReadMasterType