1 -- ************************************************************************** --
2 -- ************* BittWare Incorporated ************* --
3 -- ************* 9 Hills Ave, Concord, NH
03301 ************* --
4 -- ************************************************************************** --
6 -- Copyright (c) 2012 BittWare, Inc. --
7 -- The user is hereby granted a non-exclusive license to use and or --
8 -- modify this code provided that it runs on BittWare hardware. --
9 -- Usage of this code on non-BittWare hardware without the express --
10 -- written permission of BittWare is strictly prohibited. --
12 -- E-mail: support@bittware.com Tel: 603-226-0404 --
13 -- ************************************************************************** --
15 --------------------------------------------------------------------------------
17 --------------------------------------------------------------------------------
20 use ieee.std_logic_1164.
all;
21 use ieee.numeric_std.
all;
23 use work.UtilityPkg.
all;
24 use work.BoardInfoPkg.
all;
25 use work.ComponentPkg.
all;
26 use work.AvalonPkg.
all;
28 use work.RegisterPkg.
all;
32 --------------------------------------------------------------------------------
34 --------------------------------------------------------------------------------
43 --------------------------------------------------------------------------------
45 --------------------------------------------------------------------------------
62 --------------------------------------------------------------------------------
64 --------------------------------------------------------------------------------
67 --------------------------------------------------------------------------------
69 --------------------------------------------------------------------------------
72 --------------------------------------------------------------------------------
74 --------------------------------------------------------------------------------
77 --------------------------------------------------------------------------------
79 --------------------------------------------------------------------------------
82 --------------------------------------------------------------------------------
84 --------------------------------------------------------------------------------
95 -- Other common generic interace parameters
98 -------------------------------
99 -- Memory Interface Parameters
100 -- The MASTER/SLAVE_INFO parameter is not used in most components.
101 -- In the case of this example, we are restricting the address and data
102 -- width of the memory interface so that we don't have to support reshaping of
103 -- data and variable addres widths. However, these parameters are still very
104 -- necessary when you have a component that is decoding or switching
105 -- the memory interface.
106 -------------------------------
108 --MASTER_INFO : AvalonMMMasterInfo
109 -- Master Array Interface
111 --MASTER_INFO : AvalonMMMasterInfoArray;
112 -------------------------------
114 --SLAVE_INFO : AvalonMMSlaveInfo;
115 -- Slave Array Interface
117 --SLAVE_INFO : AvalonMMSlaveInfoArray;
118 -------------------------------
119 -- In the rare occation when there is an input and output interface and both
120 -- share the same configuration info, use the IN/OUT subfix to specify parameters.
121 -- SLAVE/MASTER_IN/OUT_PORTS : ;
122 -- SLAVE/MASTER_IN/OUT_INFO : AvalonMM(Master/Slave)Info;
123 -- SLAVE/MASTER_IN/OUT_INFO : AvalonMM(Master/Slave)InfoArray;
124 -------------------------------
125 -- Streaming Data Interface
126 --DATA_INFO : AvalonSTInfo;
127 -- OR if the inputs and outputs don't match
128 --DATA_IN_INFO : AvalonSTInfo;
129 --DATA_OUT_INFO : AvalonSTInfo;
130 -------------------------------
131 -- Streaming Array Interface
133 --DATA_INFO : AvalonSTInfoArray;
135 --DATA_INFO : AvalonSTInfoArray(0 to DATA_PORTS-1);
136 -------------------------------
137 -- Streaming Array Input/Output Interfaces
139 --DATA_IN_INFO : AvalonSTInfoArray;
141 --DATA_OUT_INFO : AvalonSTInfoArray
148 slaveIRQ : out AvalonIRQSenderIntfArray(2 downto 0);
164 -- Other common Avalon Interface Combinations
167 -------------------------------
171 --masterIRQ : in AvalonIRQReceiverIntf;
172 -- Master Input Interface
173 --masterIn : in AvalonMMMasterToFabricIntf;
174 --masterInRsp : out AvalonMMFabricToMasterIntf;
175 -- Master Output Interface
176 --masterOut : out AvalonMMMasterToFabricIntf;
177 --masterOutRsp : in AvalonMMFabricToMasterIntf;
178 -------------------------------
182 --slaveIRQ : out AvalonIRQSenderIntf;
183 -- Slave Input Interface
184 --slaveIn : in AvalonMMFabricToSlaveIntf;
185 --slaveInRsp : out AvalonMMSlaveToFabricIntf;
186 -- Slave Output Interface
187 --slaveOut : out AvalonMMFabricToSlaveIntf;
188 --slaveOutRsp : in AvalonMMSlaveToFabricIntf;
189 -------------------------------
190 -- Master Array Input Interface
191 --masterIn : in AvalonMMMasterToFabricIntfArray(0 to MASTER_PORTS-1);
192 --masterInRsp : out AvalonMMFabricToMasterIntfArray(0 to MASTER_PORTS-1);
193 -- Master Array Output Interface
194 --masterOut : out AvalonMMMasterToFabricIntfArray(0 to MASTER_PORTS-1);
195 --masterOutRsp : in AvalonMMFabricToMasterIntfArray(0 to MASTER_PORTS-1);
196 -------------------------------
197 -- Slave Array Input Interface
198 --slaveIn : in AvalonMMFabricToSlaveIntfArray(0 to MASTER_PORTS-1);
199 --slaveInRsp : out AvalonMMSlaveToFabricIntfArray(0 to MASTER_PORTS-1);
200 -- Slave Array Output Interface
201 --slaveOut : out AvalonMMFabricToSlaveIntfArray(0 to MASTER_PORTS-1);
202 --slaveOutRsp : in AvalonMMSlaveToFabricIntfArray(0 to MASTER_PORTS-1);
203 -------------------------------
204 -- Single Rate Component Clock Input
207 -- Multi-Rate Component Clock Input
210 -- Multi-Rate Component Clock Output
212 --dataOutReset : in ;
213 -------------------------------
214 -- Streaming Input Interface
215 --dataIn : in AvalonSTSourceToSinkIntf;
216 --dataInRsp : out AvalonSTSinkToSourcercIntf;
217 -- Streaming Array Input Interface
218 --dataIn : in AvalonSTSourceToSinkIntfArray(0 to DATA_IN_PORTS-1);
219 --dataInRsp : out AvalonSTSinkToSourceIntfArray(0 to DATA_IN_PORTS-1);
220 -- Here is another example except you can defer the sizing.
221 --dataIn : in AvalonSTSourceToSinkIntfArray;
222 --dataInRsp : out AvalonSTSinkToSourceIntfArray;
223 -------------------------------
224 -- Streaming Output Interface
225 --dataOut : out AvalonSTSourceToSinkIntf;
226 --dataOutRsp : in AvalonSTSinkToSourceIntf;
227 -- Streaming Array Output Interface
228 --dataOut : out AvalonSTSourceToSinkIntfArray(0 to DATA_OUT_PORTS-1);
229 --dataOutRsp : in AvalonSTSinkToSourceIntfArray(0 to DATA_OUT_PORTS-1);
230 -------------------------------
232 --eventCtrl : out AvalonSTEventIntf;
233 --eventStatus : in AvalonSTEventIntf;
234 -- Event Interface Array
235 --eventCtrl : out AvalonSTEventIntfArray;
236 --eventStatus : in AvalonSTEventIntfArray;
238 --------------------------------------------------------------------------------
240 --------------------------------------------------------------------------------
242 --------------------------------------------------------------------------------
244 --------------------------------------------------------------------------------
252 --------------------------------------------------------------------------------
254 --------------------------------------------------------------------------------
259 --------------------------------------------------------------------------------
261 --------------------------------------------------------------------------------
264 --------------------------------------------------------------------------------
266 --------------------------------------------------------------------------------
268 ---------------------------
270 ---------------------------
272 -- By declaring some range types, access of data is easier. Add more, remove
273 -- some. Do whatever makes it easiest to get at the data fields and meets
274 -- design requirements. Oh, just don't hardcode BITS
275 -- For ports using a single sizing...use DATA_INFO/WIDTH/RANGE
276 --constant DATA_WIDTH : := DATA_INFO.BITS_PER_SYMBOL*DATA_INFO.SYMBOLS_PER_BEAT;
277 --subtype DATA_RANGE is range (DATA_WIDTH-1) downto 0;
287 ---------------------------
288 -- Register Configuration
289 ---------------------------
295 ------------------------------------------------------------------------------
296 -- DOXYGEN INSTRUCTIONS
297 ------------------------------------------------------------------------------
298 -- DOXYGEN: Register Description Instructions:
299 -- DOXYGEN: Add a group named for this component. All of the component's registers
300 -- DOXYGEN: will be add to this group. Describe the group detail with the
301 -- DOXYGEN: tag, @details, and add an @see to link back to the architecture.
302 -- DOXYGEN: Create a group with the same name as the register. Describe the
303 -- DOXYGEN: register with @details tag and add an @see link back to the architecture
304 -- DOXYGEN: The @{ and @} bound the group. The entity group name must be unique.
305 -- DOXYGEN: Describe the register bits with the @details tag
306 ------------------------------------------------------------------------------
318 constant CONTROL_REGISTER : RegisterLocation := init( "example_control", REG_COMPONENT_START_ADDR+toInt(x"00"), 3, RW_REG_CFG );
334 constant STATUS_REGISTER : RegisterLocation := init( "exmaple_status", REG_COMPONENT_START_ADDR+toInt(x"01"), 8, RO_STATUS_REG_CFG );
338 constant FULL_BIT : RegisterBit := FIFO_WR_FULL_BIT;
349 constant COUNT_CONFIG_REGISTER : RegisterLocation := init( "count_config", REG_COMPONENT_START_ADDR+toInt(x"02"), 2, RW_WR_CLEAR_REG_CFG );
440 -- If for some reason, only 1 RegisterLocation
is desired, the syntax would be as follows:
441 --constant COMPONENT_REG_LOCATIONS : RegisterLocationArray := (0 => CONTROL_REGISTER);
443 ---------------------------
444 -- Register Bank Setup
445 ---------------------------
447 -- NOTE: All the standard addresses are defined in RegisterPkg.vhd
449 -- UPDATE THE COMPONENT VERSION NUMBER...
464 ---------------------------
465 -- FIFO Configuration
466 ---------------------------
475 WR_ALMOST_EMPTY_CNT => FIFO_REMOVE_COUNT,
476 RD_ALMOST_FULL_CNT => FIFO_REMOVE_COUNT,
477 RD_ALMOST_EMPTY_CNT => 1,
478 SHOW_AHEAD => true );
483 ---------------------------
484 -- Signal Declarations
485 ---------------------------
495 -- Write clear signals
502 -- Read Clear Signals
506 -- IRQ example signal
509 -- Register Bank Signals
513 -- Input FIFO signals
518 -- Output FIFO signals
522 ---------------------------
524 ---------------------------
526 -- synthesis translate_off
527 use work.ctype_h.
all;
528 use work.strings_h.
all;
529 use work.stdio_h.
all;
533 constant FILE_NAME : FileName := init( "project_config.xml" );
534 variable xml_file : CFILE;
536 xml_file := fopen(FILE_NAME, "a");
538 if( xml_file = 0 ) then
539 report "ERROR: ExampleComponent.vhd - Cannot Open XML File " & FILE_NAME
543 fprintf(xml_file, "<ComponentInfo type=%s name=%s>\n", addQuotes("ExampleComponent"), addQuotes(NAME) );
544 fprintf(xml_file, "%s", getXML("data_in_info", DATA_IN_INFO));
545 fprintf(xml_file, "%s", getXML("data_out_info", DATA_OUT_INFO));
546 fprintf(xml_file, "</ComponentInfo>\n");
554 -- synthesis translate_on
556 --------------------------------------------------------------------------------
558 --------------------------------------------------------------------------------
560 ------------------------------------------------------------------------------
561 -- Component Assertions
562 ------------------------------------------------------------------------------
565 assert( true ) report "ExampleComponent.vhd - Message goes here..." severity error;
568 report "ExampleComponent.vhd - Input profile must be AVALON_ST_TYPICAL"
572 report "ExampleComponent.vhd - Output profile must be AVALON_ST_TYPICAL"
575 ------------------------------------------------------------------------------
576 example_gen : if( false ) generate
577 ------------------------------------------------------------------------------
578 -- generate specific declarations here...
581 -- This isn't needed for this example, but here is how you do one...
583 ------------------------------------------------------------------------------
585 ------------------------------------------------------------------------------
587 ------------------------------------------------------------------------------
589 ------------------------------------------------------------------------------
597 -- Avalon-MM Slave Interfaces
603 -- Register Interface
610 ------------------------------------------------------------------------------
611 -- Register Soft Reset
612 ------------------------------------------------------------------------------
614 -- Please don't use the soft reset to reset the RegisterBank slave
615 -- or register interface. It won't work, I PROMISE!
619 -- We don't want to drive reset lines with combinational logic
620 -- In this case, resets are already synchronized, just register the signal.
621 -- If we needed to synch to a different clock domain, this
622 -- soft reset component will come in handy.
625 -- Min Cycles to Hold Reset
634 ------------------------------------------------------------------------------
636 ------------------------------------------------------------------------------
639 -- If data and mem clocks are not the same, this will perform a retime and
640 -- ease up on timing constraints. Anything critical requires a fifo
641 -- for retiming. Especially on the readback side.
642 -- The best method for retiming a control signal is to have the master
643 -- drive all the configuration registers and then set a single
644 -- to latch in the update using a the read and write pulse/clear register access
645 -- modes. The standard register bank will automaticically retime those flags.
652 -- If necessary, clear the control signals here...
662 -- Some example read/write registers. One could also use the
663 -- getValue functions defined in RegisterPkg.vhd
666 -- OR: control_field <= reg_ctrl.memory(getAddr(CONTROL_REGISTER))(SOME_CTRL_RANGE);
667 -- OR: control_field <= getValue( reg_ctrl, getAddr(CONTROL_REGISTER), control_field );
668 -- OR: control_field <= getValue( reg_ctrl, getAddr(CONTROL_REGISTER), control_field'length, control_field'low );
670 -- Next is a block of configuration registers that should only be updated once.
671 -- For instace, with a write clear register. In this case, we will allow
672 -- the host to write all the configs and then set a load to latch in the new config.
673 -- This can be done with a write pulse also, in which case the last register written
674 -- to triggers a pulse, to indicate the data write is completed.
675 -- With a write clear, the flag will be cleared so that it is only active for
676 -- a single cycle. Be sure to set the access mode to write clear.
677 -- The write clear type register can also be used to latch status, increment
678 -- a counter, write a fifo, or...
679 -- The register bank will automatically retime the flags from the slave clock
680 -- to the register interface clock in standard mode.
687 -- In some cases, you may want to latch a write clear register. In that case,
688 -- check the write clear flag and then grab your data. Be careful doing this
689 -- with a bus though because all the bits might not be stable crossing clock
690 -- domains...if you aren't using the standard register bank. Always best with
692 -- Latch the only when the register is written,
696 -- Any of the read clear registers implemented should have an associated
697 -- flag that gets set when the address is read. The register bank
698 -- feeds back a flag so that the component knows to perform the clear.
699 --clear_flags <= reg_ctrl.flags(FLAGS_REGISTER.ADDR);
703 -- One could even check another register when the flag is set and
704 -- use that to determine if some flags should be cleared or not.
705 --clear_flags <= getValue( reg_ctrl, CLEAR_CTRL_REGISTER, CLEAR_FLAGS_BIT );
707 -- This register is used to set the IRQ bits as an example
714 ------------------------------------------------------------------------------
716 ------------------------------------------------------------------------------
721 -- This process doesn't need to be clocked if slaveClk = dataClk but it won't do
722 -- anything but add a cycle of latency over a slow status interface anyways.
723 -- Don't forget to somehow clear the status on reset.
726 reg_status <= initRegisterStatusIntf;
728 -- Custom Component Registers
729 reg_status.memory(STATUS_REGISTER.ADDR)(ALMOST_FULL_BIT) <= fifo_in_status.readdata(FIFO_WR_ALMOST_FULL_BIT);
730 reg_status.memory(STATUS_REGISTER.ADDR)(FULL_BIT) <= fifo_in_status.readdata(FIFO_WR_FULL_BIT);
731 reg_status.memory(STATUS_REGISTER.ADDR)(ALMOST_EMPTY_BIT) <= fifo_in_status.readdata(FIFO_RD_ALMOST_EMPTY_BIT);
732 reg_status.memory(STATUS_REGISTER.ADDR)(EMPTY_BIT) <= fifo_in_status.readdata(FIFO_RD_EMPTY_BIT);
734 -- Below is an example read clear register. Basically, each a register of this type
735 -- is read, the register bank will send us a flag letting us know. When the flag is seen,
736 -- that is a trigger to clear the internal component register. The read clear can be
737 -- used for flags, interrupts, or any other type of transaction with a desired read and
738 -- clear. The control process is used to check the read clear flag.
739 -- A similar register access mode is the read pulse, however, the register need not be
740 -- cleared on the pulse.
743 -- Set the IRQ status register bits using a procedure.
751 ------------------------------------------------------------------------------
753 ------------------------------------------------------------------------------
758 constant INIT_CNT
: := 10;
764 flags <= (
others => '0');
765 elsif( pause = '0' ) then
767 -- When we see the clear flag read event, clear the
770 flags <= (
others => '0');
773 -- Looks like we got a load event
774 if( load = '1' ) then
779 -- Set the flags when our counter is done to create some
781 if( done = false and cnt = 0 ) then
782 flags <= (
others => '1');
786 if( done = false ) then
794 ------------------------------------------------------------------------------
796 ------------------------------------------------------------------------------
798 -- FIFO is used for flow control. If a depth of more than 16 or so
799 -- is required, you would go to a RAM based FIFO...
800 -- The single rate fifo is register based so you don't always want to use it.
801 -- HINT: using a fifo on the input makes avalon backpressure easier to implement
802 -- without dropping data at certain times, so it is not recommeneded to
803 -- take the fifo out.
807 REG_BANK_CFG => SMALL_REG_BANK_CONFIG,
808 -- Avalon-ST Parameters
814 -- Avalon-MM Slave Interfaces
816 -- Avalon-ST Input Interface
821 -- Avalon-ST Output Interface
828 ------------------------------------------------------------------------------
829 -- Processing Code and Output Combined
830 ------------------------------------------------------------------------------
832 -- Apply back pressure when output is not ready
837 -- Let's do something here.
838 -- Assume that SYMBOLS_PER_BEAT is equal to one to avoid a data reshape.
839 -- In some components the data may need to be reshaped. Usually in multi-rate components.
840 -- Also assuming AVALON_ST_TYPICAL profile.
842 -- NOTE: This process was implemented specifically for communication with an output
843 -- data FIFO. Otherwise, this code would violate the Avalon spec. It utilizes the
844 -- response ready flag as a FIFO not empty flag. Following the Avalon spec,
845 -- it is required that the valid is NOT set conditional on the ready when the ready
846 -- latency is set to zero. Valid should typically be independent of ready.
848 variable disable_while_valid : ;
853 disable_while_valid := false;
856 -- At this point, a few conditions could have occured.
857 -- 1. We set valid
on the previous cycle
and it was accepted.
858 -- 2. We set valid
on the previous cycle
and it was
not accepted.
859 -- 3. We didn't send data at
all on the previous cycle
861 -- Check the disable flag to help us restart
862 if( disable_while_valid = true ) then
864 disable_while_valid := false;
866 -- The sink was ready to accept data on the previous cycle
871 -- Either way, transfer the next data point. This is where our
872 -- signal processing would occur.
876 -- The sink was not ready to accept data on the previous cycle
881 -- Hold right where we are
885 -- Don't do anything once again. But you can present
886 -- the next data here if you want to stick to the
894 -- The component is disabled so stop all transfers
897 -- Set a disable flag if the data was not accepted
899 disable_while_valid := true;
907 ------------------------------------------------------------------------------
909 ------------------------------------------------------------------------------
914 -- Avalon-ST Parameters
920 -- Avalon-ST Input Interface
925 -- Avalon-ST Output Interface
932 --------------------------------------------------------------------------------
934 --------------------------------------------------------------------------------