1
0
mirror of https://github.com/pConst/basic_verilog.git synced 2025-01-14 06:42:54 +08:00

Added Xilinx Picoblaze and its Altera version Pacoblaze as a great HDL programming examples

This commit is contained in:
Konstantin Pavlov (pt) 2016-03-24 21:10:37 +03:00
parent c31bb14628
commit 9e19abc733
428 changed files with 173167 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,599 @@
<EFBFBD> Copyright 2010-2014, Xilinx, Inc. All rights reserved.
This file contains confidential and proprietary information of Xilinx, Inc. and is
protected under U.S. and international copyright and other intellectual property laws.
Disclaimer:
This disclaimer is not a license and does not grant any rights to the materials
distributed herewith. Except as otherwise provided in a valid license issued to you
by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE MATERIALS
ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL
WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED
TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR
PURPOSE; and (2) Xilinx shall not be liable (whether in contract or tort, including
negligence, or under any other theory of liability) for any loss or damage of any
kind or nature related to, arising under or in connection with these materials,
including for any direct, or any indirect, special, incidental, or consequential
loss or damage (including loss of data, profits, goodwill, or any type of loss or
damage suffered as a result of any action brought by a third party) even if such
damage or loss was reasonably foreseeable or Xilinx had been advised of the
possibility of the same.
CRITICAL APPLICATIONS
Xilinx products are not designed or intended to be fail-safe, or for use in any
application requiring fail-safe performance, such as life-support or safety devices
or systems, Class III medical devices, nuclear facilities, applications related to
the deployment of airbags, or any other applications that could lead to death,
personal injury, or severe property or environmental damage (individually and
collectively, "Critical Applications"). Customer assumes the sole risk and
liability of any use of Xilinx products in Critical Applications, subject only to
applicable laws and regulations governing limitations on product liability.
THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
-------------------------------------------------------------------------------------------------
KCPSM6 : Known Issues and Workarounds
-------------------------------------------------------------------------------------------------
This file was included with KCPSM6 Release 9 - 30th September 2014.
Ken Chapman - Xilinx Ltd - 30th September 2014
This document contains known issues and workarounds with PicoBlaze or when using PicoBlaze in an
ISE or Vivado design environment. For more general discussion and to share ideas and experiences
please visit the PicoBlaze forum. It is likely that commonly asked questions will be discussed
here and threads provide a resource for everyone to be able to read.
http://forums.xilinx.com/t5/PicoBlaze/bd-p/PicoBlaze
Xilinx Technical support is also available to answer your questions. However it is recommended
that you take the time to consider exactly what your issue is before asking any questions. Just
because your design contains a PicoBlaze processor doesn't mean you actually have a problem
with PicoBlaze! If you are a Xilinx novice and encounter difficulties then make sure you can
get a simple HDL design through ISE or Verilog before including PicoBlaze.
http://www.xilinx.com/support/clearexpress/websupport.htm
-------------------------------------------------------------------------------------------------
Contents
-------------------------------------------------------------------------------------------------
Potential issues when using ISE 12.x
JTAG Loader requires ISE/ChipScope when using Vivado
'The XILINX environment variable is not set or is empty'
'The program can't start because libCsdFpga.dll is missing...'
'PCMSVCR100.dll' or 'MSVCR100.dll' is missing or could not be found
KCPSM6 program memory can be corrupted when configuring device with Vivado 'Hardware Manager'.
KCPSM6 size may vary when using Vivado
WARNING:Xst:647 - Input <instruction<0:11>> is never used
INFO:Xst:2261 or WARNING:Xst:1710 messages relating to Unit <jtag_loader_6>
JTAG Loader not working
JTAG Loader may take ~25 seconds to load a new program when using an ATLYS board
Designs containing multiple KCPSM6 processors
'global_opt' may result in incorrect implementation
'Pack:2811' errors in MAP when using ChipScope
'Pack:2811' errors in MAP when using 'Keep Hierarchy' and design contains multiple KCPSM6.
'Pack:2811' errors in MAP when using a low 'Max Fanout' value in XST.
'PhysDesignRules:1422' errors reported by BITGEN
JTAG Loader and BSCAN Users
KCPSM6 program memory can be corrupted when using ChipScope Analyser
KCPSM6 program memory can be corrupted when using Vivado Hardware Manager
Poor Display of Strings in ISE Simulator
KCPSM6 Assembler window takes a long time to appear on screen
-------------------------------------------------------------------------------------------------
Descriptions
-------------------------------------------------------------------------------------------------
Potential issues when using ISE 12.x
------------------------------------
Using ISE v12.x may result in XST generating errors similar to the following...
HDLCompiler:1314 - "<program_ROM_filename>.vhd" Line 390:
Formal port/generic <rdaddr_collision_hwconfig> is not declared in <ramb18e1>
The logic primitives including BRAM are defined in libraries that XST reads as it elaborates
your design. Not surprisingly these libraries change with each release of the ISE tools. In
particular the ISE v13.x tools introduced support for the 7-Series devices a obviously this
required quite significant additions and alterations to the underlying libraries.
The ROM_form templates have been prepared to match with the libraries provided with ISE v13.x
and therefore the potential exists for a something to be absent from an older library
resulting in a error similar to that shown above.
It is recommended that you use ISE v13.2 or later with KCPSM6 but if this is not convenient
then simply replace the default 'ROM_form.vhd' or 'ROM_form.v' template with a copy of an
older template that was supplied with 'Release 2' of KCPSM6 and included in this package
for your convenience.
Provided for use with ISE v13.x or later
ROM_form_JTAGLoader_14March13.vhd
ROM_form_JTAGLoader_14March13.v
Provided for use with ISE v12.x only
ROM_form_JTAGLoader_3Mar11.vhd
ROM_form_JTAGLoader_3Mar11.v
JTAG Loader requires ISE/ChipScope when using Vivado
----------------------------------------------------
In order to use JTAG loader the drivers associated with ChipScope must be present. These
drivers provide access the Platform Cable USB or the equivalent Digilent circuit. It is
therefore necessary to also have an installation of ChipScope which is part of the ISE
tools. Please see page 25 of 'PicoBlaze_Design_in_Vivado.pdf' which presents a simple
batch file that will set environment variables that specify the location of ISE on you
PC so that JTAG Loader will be able to work.
'The XILINX environment variable is not set or is empty'
'The program can't start because libCsdFpga.dll is missing...'
--------------------------------------------------------------
The 'PATH' and 'XILINX' environment variables must be correctly set to the location of
an ISE installation. Please see one or more of the following for further details...
'READ_ME_FIRST.txt' - 'System Requirements' section.
'KCPSM6_User_Guide_30Sept14.pdf' - Page 25.
'PicoBlaze_Design_in_Vivado.pdf' - Page 25.
'PCMSVCR100.dll' or 'MSVCR100.dll' is missing or could not be found
-------------------------------------------------------------------
The following description is also to be found in the 'System Requirements' section of the
'READ_ME_FIRST.txt' file.
JTAG Loader must also be able to access some system level DLL files. In the case of a Windows-XP
environment then it is normal for the PATH to contain 'C:\WINDOWS\system32;' or similar. So if
you receive a system error indicating that 'PCMSVCR100.dll' is missing or could not be found then
add the appropriate definition to your PATH. When using a Windows-7 environment it is more likely
that 'MSVCR100.dll' will become the subject of a system error message. 'MSVCR100.dll' is not part
of a default Windows-7 installation but is a often present as a result of a Microsoft Visual C++
application. If you do encounter this issue then the quickest solution is to place a copy of
'msvcr100.dll' provided in the 'JTAG_Loader' directory of this package in to the same directory
as the JTAG Loader executable you are invoking.
KCPSM6 program memory can be corrupted when configuring device with Vivado 'Hardware Manager'.
----------------------------------------------------------------------------------------------
Vivado 'Hardware Manager' results in the same memory corruption issue as described in
'KCPSM6 program memory can be corrupted when using ChipScope Analyser'. In this case the only
workarounds are either to use iMPACT to configure your device or to write your program in a way
that avoids address 003. For example, placing the following at the start of a program will ensure
that the corrupted location is not executed at all.
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> JUMP cold_start ;Avoid address 003 on start up
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> JUMP cold_start
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> JUMP cold_start
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> JUMP cold_start ;Address 003
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
cold_start: <normal program code starts here>
KCPSM6 size may vary when using Vivado
--------------------------------------
When using Vivado to implement a design, KCPSM6 will probably occupy more than the 26-32
Slices predictably achieved when using the ISE tools and quoted in the documentation. The
maximum performance may also be lower. Vivado (at least up to 2014.2), ignores the Slice
packing directives (i.e. HBLKNM attributes) contained in the source VHDL and Verilog files
and this tends to result in KCPSM6 being distributed across a larger number of Slices. Vivado
packs designs more tightly the more a design fills a given device so this is not a significant
issue. However, the size reports can be misleadingly large when implementing a simple test case.
The architecture of UltraScale devices is somewhat different in that every Slice has 8 LUTs
rather than the 4 LUTs in the Slices of Spartan-6, Virtex-6 and 7-Series devices. It is
therefore expected that KCPSM6 would appear to occupy less Slices in an UltraScale device
but that is really just a difference in architecture.
Unrecognised 'RAMB18E2' Primitives in Program Memory when using ISE
-------------------------------------------------------------------
This will happen if you assembled your program whilst using the 'ROM_form' template intended
for use with Vivado (e.g. 'ROM_form_JTAGLoader_Vivado_2June14.vhd'). When using ISE you should
assemble your programs using a copy of 'ROM_form_JTAGLoader_14March13.vhd' which is the original
template compatible with ISE. Alternatively, assemble your program using one of the 'production
templates' consistent with the target device and memory size required.
WARNING:Xst:647 - Input <instruction<0:11>> is never used
---------------------------------------------------------
XST in ISE v12.x and ISE v13.x incorrectly reports the following warning message....
WARNING:Xst:647 - Input <instruction<0:11>> is never used.
This warning can safely be ignored. However, it should be recognised that if a similar warning
message reports that all 18-bits of instruction (instruction<0:17>) are never used then it
probably means that you really didn't connect the program memory to KCPSM6 correctly.
This issue was fixed in ISE version 14.1.
INFO:Xst:2261 or WARNING:Xst:1710 messages relating to Unit <jtag_loader_6>
---------------------------------------------------------------------------
XST typically issues two or three messages concerning 'FF/Latch <control_dout_int_2>' or
similar when the design has JTAG Loader enabled. These messages can be safely ignored because
they reflect the way in which certain signals have been assigned the same constant values
which the JTAG Loader utility will later use to understand your PicoBlaze design (e.g. a value
defining the size of your program memory).
Once JTAG Loader is disabled or a production 'ROM_form' template is used there should be no
messages of this kind.
Note that XST issues 'INFO' messages when the program memory file is VHDL and 'WARNING' messages
when the program memory file is Verilog. Hence, if you use a VHDL file to define your program
memory the messages will become 'INFO' even if the remainder of your project is Verilog.
JTAG Loader not working
-----------------------
If you experience any issues related to not being able to find a DLL then please check the
'Requirements' section above to ensure that your environment variables are set appropriately.
Vivado users must install ChipScope provided with ISE (see 'Requirements')
JTAG Loader may not work correctly if you have more that Platform Cable USB connected to your
PC at the same time so the obvious workaround is only to connect the cable associated with
the chain in which your target device is located. Please note that many development boards and
evaluation kits such as ATLYS or ML605 boards have Platform Cable USB circuit or Digilent
equivalent included on them so the most common reason for appearing to have multiple cables
connected is when one or more of these boards are connected (or one of these boards and a real
Platform Cable USB).
JTAG Loader may take ~25 seconds to load a new program when using an ATLYS board
--------------------------------------------------------------------------------
Loading a KCPSM6 program normally takes about 5 seconds so this issue is under investigation.
However, it is only a case of being slower than expected; operation is correct and reliable.
Designs containing multiple KCPSM6 processors
---------------------------------------------
It is common practice for designs to contain multiple instances of PicoBlaze with each typically
acting as an independent 'state machine'. There are also some designs in which hundreds, or even
thousands, are used to implement amazing structures and algorithms. Regardless of how many
KCPSM6 processors are included, the use model and design method is really the same for each
instance so there is really very little to consider just because there is more than one. That
said, the following points may be helpful in making your multi-KCPSM6 enjoyable.
When using the default 'ROM_form' template your assembled program file provides you with the
option to enable the JTAG Loader circuit. However, you do need to remember that only one program
memory can have this feature enabled at any time. Hence, only one instance can have
'C_JTAG_LOADER_ENABLE' assigned the value '1' and all other instances must be assigned '0'.
Although compliance with the fundamental limitation described above should result in a design
that will successfully pass through the ISE tools you will find that WARNING messages are
generated for each instance or program memory assembled using the default 'ROM_form' template.
This is because the default 'ROM_form' template includes the definition of the JTAG Loader
circuit and this means that synthesis observes a repeated definition of the JTAG Loader circuit
(and a function) in each instance irrespective of the loader being enabled or not. These warnings
can be safely ignored but if you are looking for more elegance (and why shouldn<64>t you?), then
here are two techniques for you to consider.
a) Replace the default 'ROM_form' template with the appropriate 'Production Memory' template.
These are described on page 47 of the KCPSM6 user guide and in 'kcpsm6_assembler_readme.txt'.
Once a program is assembled using a production template then the memory definition file
only contains the specific BRAM(s) necessary for your application. JTAG Loader is no longer
included and hence replicated definition is avoided. Use of 'Production Memory' does require
small changes to your design (i.e. the instantiation no longer includes generics or the 'rdl'
port) but this is a recommended step before release of a product anyway and suitable once
any program has become stable.
b) If you still want to maintain the ability to enable the JTAG Loader on a program instance
in the design (obviously you can only enable one at a time) then you have to keep the
JTAG Loader option available within each instance. To avoid those warning messages you
need to ensure that the JTAG Loader is only defined once in overall design. This ultimately
means separating the definition of JTAG Loader from the definition of the program memory.
Start by making a copy of the default template ('ROM_form_JTAGLoader_16Aug11.vhd') and remove
all items defining JTAG Loader. Locate and delete the code near the top that defines a function
called 'addr_width_calc' and all the code towards the end following the 'JTAG Loader' comment
banner that defines the actual JTAG Loader circuit. In the 'Miscellaneous' directory you can
find 'ROM_form_for_multiple_instances.vhd' which has already had these items removed from the
default template and ready for you to use.
You must (only) assemble one program using the default template which will include the definition
of JTAG Loader. All other programs must be assembled using the modified template which only
define the program memory (hint - assemble programs in different directories containing the
'ROM_form' template required).
'global_opt' may result in incorrect implementation
---------------------------------------------------
Setting 'global_opt' to anything other than 'off' (the default) in MAP when using ISE v13.1 or
ISE 13.2 may result in incorrect implementation of the KCPSM6 logic and therefore a failure to
execute code in the way expected (e.g. shift and rotate operations may not work properly). The
'area' setting may even prevent your design from passing through MAP at all. This issue had
not been observed when using ISE v12.4 and there are no issues as long as 'global_opt' is set
to 'off'. Note that when using ISE v13.2 to target a 7-Series device the 'global_opt' option
is not available and therefore this issue can only occur when targeting Spartan-6 or Virtex-6.
The cause of this issue was located and then fixed in ISE v13.4 so you should use ISE v13.4
or later when 'global_opt' needs to be set to anything other than 'off' in order to process
other parts of your design. However, a user of ISE v13.4 did still appear to have a similar
issue when ChipScope was also being used to probe inside KCPSM6.
'Pack:2811' errors in MAP when using ChipScope
----------------------------------------------
Connection of ChipScope can generate 'Pack:2811' errors in MAP. This mainly appears to happen
when connecting 'out_port' or 'port_id' directly to ChipScope. It has also been known to
happen when connecting ChipScope directly to the 'address' or 'instruction' ports.
There are four potential workarounds for this issue.
a) To insert a pipeline register between KCPSM6 and ChipScope.
b) Set the 'Keep Hierarchy' option in XST to 'Yes' (default is 'No').
However this may not work if there are more than one KCPSM6 (see below).
c) Set the following system environment variable: XIL_MAP_OLD_SAVE=1.
Close ISE.
Right click on 'My Computer' and select 'Properties'.
Go to the 'Advanced' tab and choose 'Environment Variables'.
Use 'New' or 'Edit' as necessary.
Open and run ISE again.
d) Remove or comment out all the Slice packing directives (HBLKNM attributes) in the KCPSM6
source file. The 'kcpsm6_without_slice_packing_attributes.vhd' located on the 'Miscellaneous'
directory already has these attributes commented out. Using this workaround will result in
KCPSM6 occupying more Slices and having a lower peak performance and therefore it is
better to only resort to using it if the other methods cannot be used or are unsuccessful.
'Pack:2811' errors in MAP when using 'Keep Hierarchy' and design contains multiple KCPSM6.
------------------------------------------------------------------------------------------
This error has been observed when a design contains multiple instances of KCPSM6 and
the 'Keep Hierarchy' option in XST has been set to 'Yes'. Therefore the obvious solution is
to revert to the default setting of 'No'. Alternatively the 'Allow Logic Optimization Across
Hierarchy' option in MAP can be enabled (tick box in Project navigator or apply the
-ignore_keep_hierarchy switch on the command line).
If it is undesirable to adjust your implementation settings then please see 'c' and 'd'
workarounds in the issue above.
'Pack:2811' errors in MAP when using a low 'Max Fanout' value in XST.
---------------------------------------------------------------------
The 'Max Fanout' parameter is a 'Xilinx Specific Option' for XST and has the default value
of 100000 for the devices used with KCPSM6. It has been known for very low values (e.g. <20)
to result in a subsequent error in MAP. Should this occur, please increase the value. If
you have a particular reason to use such a low value then synthesize KCPSM6 separately and
include it in your design as a 'black box'.
'PhysDesignRules:1422' errors reported by BITGEN
------------------------------------------------
Should this error report occur then it will probably look something like this....
ERROR:PhysDesignRules:1385 - Issue with pin connections and/or configuration on
block:<instance_name>/stack_ram_high_RAMD_D1>:<LUT_OR_MEM6>. For RAMMODE programming
set with DPRAM32 or SPRAM32 or SRL16 the DI2 input pin must be connected.
This error has only occurred in designs where the user has not connected all 12-bits of the
address bus to a program memory. Hence the simple and obvious solution is to ensure that
all address bits are connected to something.
Regardless of the memory size, all the supplied 'ROM_form' templates connect all address bits
to something so that these signals and associated logic are preserved. This makes it easier to
increase or decrease the memory size and avoids warning messages (as well as this error). As
such, if you have encountered this error you are probably using your own 'ROM_form' template
in which one or more of the (most significant) address bits are not required and have not been
connected to something in order to preserve them.
Whilst it is generally a good idea for unused logic to be trimmed, KCPSM6 is so optimised
to the architecture and so tightly packed into the logic Slices that any logic trimming is
insignificant. Furthermore, any trimming only leads to the formation of unusable 'holes' in
otherwise used Slices so there is nothing to be gained. This is particularly true of what
happens to the memory used to implement the program counter stack when any of the address
bits are unused and leads to the error being generated. Obviously it would be better if the
tool chain could handle this better but it just happens to be one of those cases that is
more challenging than it first appears to be!
JTAG Loader and BSCAN Users
---------------------------
The JTAG Loader utility employs a BSCAN primitive within the device to form a bridge to the
KCPSM6 program memory. Other applications may also exploit a BSCAN primitive such as ChipScope
which implements a bridge between ChipScope Analyser and an associated ICON core. The good news
is that there are four BSCAN primitives in each device so it is unlikely that you will not have
enough of them. Clearly, if you do exceed the number available then your only recourse is to
reduce the number required; possibly disabling JTAG Loader so that the rest of your design can
fit will be the easiest solution.
However, since there are normally enough BSCAN primitives available, the more common issue
relates to the allocation of the 'USER' address to each BSCAN primitive. As provided, the JTAG
Loader is assigned to 'USER2'. When generating an ICON core for ChipScope there is an option to
set the 'boundary scan' value to USER1, USER2, USER3 or USER4 but this is normally set to 'USER1'
so in most cases ChipScope and JTAG Loader happily co-exist.
If you find it necessary to assign JTAG Loader to a different 'USER' then you will need to
make a small adjustment to hardware and use JTAG Loader with the '-i' option as shown below.
To modify the hardare, open the default 'ROM_form' template and locate the line shown below and
adjust the number '2' to '1', '3' or '4' as desired...
'ROM_form.vhd' (approximately line 256 and part of 'component jtag_loader_6')
C_JTAG_CHAIN : integer := 2;
'ROM_form.v' (approximately line 295 and part of 'module jtag_loader_6')
parameter integer C_JTAG_CHAIN = 2;
You will then need to assemble your PSM file such that the new assignment is transferred into
your actual design file. Obviously, since this is a change to the hardware definition you must
also process the whole design, generate a BIT file and configure the device with it too.
When you run the JTAG Loader utility it assumes the default USER number is '2' so you will now
need to use the '-i' option to specify the same USER number that you defined in your template.
For example, if the line in the VHDL template was changed to 'C_JTAG_CHAIN : integer := 4;'
then to update the KCPSM6 program using JTAG Loader the command will be...
jtagloader -i4 -l your_program.hex
(where 'jtagloader' is the required executable for your operating system).
KCPSM6 program memory can be corrupted when using ChipScope Analyser.
---------------------------------------------------------------------
If your PicoBlaze design has JTAG Loader enabled and the device is configured with the BIT
file using ChipScope Analyser (rather than iMPACT) then this can result in corruption to one
location of the program memory. Other uses of ChipScope may also result in the same corruption
which will almost certainly be to the 4th instruction in the program memory (address 003) and
result in that location being cleared to 00000 Hex. This value is equivalent to a 'LOAD s0, s0'
instruction which will do nothing but obviously that still means that your intended instruction
is missing and effect the execution of your program.
Note that there does not need to be a ChipScope Core in the design, it is purely the act of
using ChipScope Analyser that has this effect even if it is only used to configure the device.
The issue is related to the way ChipScope Analyser searches for a ChipScope core in your design
and that process interfering with JTAG Loader which makes use of a BSCAN primitive in a very
similar way to that of a ChipScope core.
If you suspect that this is happening then JTAG Loader can be used to confirm it using its
read back facility. First read back the contents of the memory into a temporary hex file...
jtagloader -r temp.hex
Then compare the contents of this hex file with the hex file generated by the KCPSM6 assembler
for your program. It should be easy to see the '00000' value near the top of the file if
corruption has taken place.
Fortunately there are several workarounds:-
a) Use iMPACT rather than ChipScope to configure the device with your BIT file.
b) Following configuration by ChipScope Analyser, use JTAG Loader to refresh the program
memory with a valid image (you will do this naturally if using JTAG Loader during
program development).
c) Disable JTAG Loader if you don't need to use it.
d) Start your PSM program with directive 'ADDRESS 004' such that your code begins at
address 004. In this way the first four locations of memory will default to 00000 hex
('LOAD s0, s0' has no effect) and the clearing effect of the corruption will become
irrelevant. Note that the DEFAULT_JUMP directive would override this default though.
e) Place the following instructions at the start of your program so that address 003
is avoided.
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> JUMP cold_start ;Avoid address 003 on start up
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> JUMP cold_start
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> JUMP cold_start
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> JUMP cold_start ;Address 003
<20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> ;
cold_start: <normal program code starts here>
f) Modify the ChipScope Analyser project file '.cpj' as described below.
Note that this method requires ISE v13.3 or later to work correctly.
i) Insert the line 'avoidUserRegDevice0=2' in your '.cpj' file.
For example...
#ChipScope Pro Analyzer Project File, Version 3.0
#Tue Aug 20 16:17:05 BST 2013
avoidUserRegDevice0=2
device.0.configFileDir= ....
This tells ChipScope Analyser to avoid 'USER2' which is assigned to JTAG Loader
from being scanned in the first device (device '0') in the JTAG chain. Adjust
'avoidUserRegDevice0' as appropriate for the device position in your JTAG chain.
ii) Start ChipScope Anaylser and open the project (.cpj file). You must do this first.
iii) Then you can 'Open Cable/Search JTAG Chain' and you should see a messages similar
to "INFO: Skipping xsdb core scan on device 0, user register 2" displayed in
the console confirming that 'USER2' has been avoided.
iv) Configure your device (probably worth using 'jtagloader -r' to confirm that
everything worked correctly the first time you try it but should be Ok after that).
Answer Record 19337 (http://www.xilinx.com/support/answers/19337.htm) may also be
useful reference when using ChipScope Analyser.
KCPSM6 program memory can be corrupted when using Vivado Hardware Manager
-------------------------------------------------------------------------
This is very similar to the known issue described immediately above but there are fewer options
when it comes to implementing a workaround. Please see page 24 of 'PicoBlaze_Design_in_Vivado.pdf'
for more details of this known issue.
Poor Display of Strings in ISE Simulator
----------------------------------------
The way in which iSim (in ISE) displays text strings is not ideal for the observation of
'kcpsm6_opcode' and 'kcpsm6_status' during simulation. It seems unlikely that this will be
rectified in ISE. These text strings are displayed correctly when using the Vivado Simulator.
KCPSM6 Assembler window takes a long time to appear on screen
-------------------------------------------------------------
In most cases the assembler window should open almost immediately so if it takes more than a few
seconds, especially if your PC is not busy processing other applications, then this is worthy of
some investigation and an experiment. Have a look to see what your default printer is set to...
Start -> Printers and Faxes
The default printer will have a small tick next to it. Ideally you should assign a local printer
and make sure that the selected printer is available to Windows applications (a printer
doesn't actually need to be turned on but should be capable of printing from applications
e.g., a USB connected printer will normally automatically turn on when sent a document).
Right click on the desired printer and select 'Set as Default Printer'.
The small tick mark will move.
Run the KCPSM6 assembler again and see if that has made it open faster. If it is not convenient
to change the default printer then the quickest and easiest way to use KCPSM6 in interactive
mode. Run KCPSM6 and wait for it to open. Then enter the name of your PSM file and let it
assemble your PSM code. Then just leave the KCPM6 assembler open and then use the 'R' and 'N'
options to control assembly. In this way you avoid having to wait for the assembler to open
each time.
Although rare, this issue typically occurs when a network printer has been assigned as the
default but the Windows applications cannot find it. This can also be associated with the print
driver being incorrect or requiring an update. If the network and/or printer driver can not
be resolved then consider assigning a local printer as the default. If you don't have a physical
local printer then a useful technique is to install a PDF writer and make that your default
printer.
-------------------------------------------------------------------------------------------------
End of file 'READ_ME_FIRST.txt'
-------------------------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,858 @@
<EFBFBD> Copyright 2010-2014, Xilinx, Inc. All rights reserved.
This file contains confidential and proprietary information of Xilinx, Inc. and is
protected under U.S. and international copyright and other intellectual property laws.
Disclaimer:
This disclaimer is not a license and does not grant any rights to the materials
distributed herewith. Except as otherwise provided in a valid license issued to you
by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE MATERIALS
ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL
WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED
TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR
PURPOSE; and (2) Xilinx shall not be liable (whether in contract or tort, including
negligence, or under any other theory of liability) for any loss or damage of any
kind or nature related to, arising under or in connection with these materials,
including for any direct, or any indirect, special, incidental, or consequential
loss or damage (including loss of data, profits, goodwill, or any type of loss or
damage suffered as a result of any action brought by a third party) even if such
damage or loss was reasonably foreseeable or Xilinx had been advised of the
possibility of the same.
CRITICAL APPLICATIONS
Xilinx products are not designed or intended to be fail-safe, or for use in any
application requiring fail-safe performance, such as life-support or safety devices
or systems, Class III medical devices, nuclear facilities, applications related to
the deployment of airbags, or any other applications that could lead to death,
personal injury, or severe property or environmental damage (individually and
collectively, "Critical Applications"). Customer assumes the sole risk and
liability of any use of Xilinx products in Critical Applications, subject only to
applicable laws and regulations governing limitations on product liability.
THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
-------------------------------------------------------------------------------------------------
KCPSM6 : PicoBlaze for Spartan-6, Virtex-6, 7-Series, Zynq and UltraScale Devices
-------------------------------------------------------------------------------------------------
Release 9.
Ken Chapman - Xilinx Ltd - 30th September 2014
Thank you for opening the 'READ_ME_FIRST' file. Don't worry, you really don't have to read all
of this file before you get started but please do review just this section to understand what
is being made available to you. I really hope you will have fun using PicoBlaze and I think you
will as long as you set off in the right direction from the outset.
Welcome to KCPSM6, the PicoBlaze optimised for Spartan-6, Virtex-6, 7-Series, Zynq and
UltraScale devices. Whether this is your first experience of PicoBlaze or you have experience of
the previous versions I hope you will find KCPSM6 useful, and most of all, fun! This package
also contains optimised UART macros (and PicoTerm) which are ideal for use with PicoBlaze
especially as so many boards provide a USB/UART interface. Several reference designs are
included in which KCPSM6 implements simple applications involving UART, I2C, SPI and XADC.
Although KCPSM6 is not difficult to use, it is highly recommended that you take some time to
look at the documentation. Before you do that, we must consider which Xilinx design tools you
will be using to target which device. As you can see from the table below, you don't always have
a choice, and certainly, only Vivado will support devices released in the future.
Device ISE (14.7) Vivado (2014.2)
Spartan-6 Yes No
Virtex-6 Yes No
7-Series
Artix 35/50/75 No Yes
Artix 100/200 Yes Yes
Kintex Yes Yes
Virtex Yes Yes
Zynq Yes Yes
UltraScale No Yes
The KCPSM6 macro is provided in the form of a VHDL or Verilog file. Although you will at some
point assemble a PSM program for PicoBlaze to execute, the assembler also generates a single
VHDL or Verilog file defining a memory holding your program. As such if you can implement a
standard HDL design using ISE or Vivado then there is really very little more for you to learn.
In fact, most competent hardware engineers report being able to implement their first design in
less than 2 hours and feeling quite proficient and productive by the end of one day.
However, it is also recognised that a large number of people using PicoBlaze for the first
time also have a tendency to be new to the world of FPGA and hardware design. Whilst it is not
possible or intended for PicoBlaze and this package to be a replacement for all the official
Xilinx documentation and customer education training materials, it is hoped that there is enough
information presented in this package to at least get anyone started and able to implement their
first small but working design that contains PicoBlaze.
If you will be using the ISE design tools then...
Open 'KCPSM6_User_Guide_30Sept14.pdf' and the first 30 pages will introduce you to
KCPSM6 and take you step by step through the creation of a working PicoBlaze design.
Once you have done this you will know most of what there is to know about the PicoBlaze
design flow and the rest of the document provides you with a manual for you to refer to
as you interactively work with PicoBlaze when implementing your own real designs.
This document does assume that you have a fundamental grasp of HDL design and have used
ISE before. If you have not, then it is strongly recommended that you first implement a
very simple design using ISE. For example, a design that simply connects some switches
to some LEDs would be enough to prepare you to use PicoBlaze for the first time. Ideally,
you will have a board that you can download your first design to and see that it works.
Alternatively, you may choose to directly use one of the reference designs provided in
this package as your starting point (i.e. known good VHDL or Verilog code).
When this package was released, ISE was version 14.7 and ideally you will be using that
version or later. As you will learn when following the documentation, the assembler needs
a 'ROM_form' template and your default starting template should be a copy of 'ROM_form.vhd'
provided in the root directory of the package or 'ROM_form.vhd' contained in the 'Verilog'
directory. In both cases these are renamed copies of 'ROM_form_JTAGLoader_14March13.vhd'
and 'ROM_form_JTAGLoader_14March13.v' respectively. If for some reason you are using ISE
version 12.x or older then please see 'Known_Issues_and_Workarounds.txt' as you will need
to use a different 'ROM_form' template to be compatible with the older version of the tools.
If you will be using the Vivado design tools then...
The first 30 pages of 'KCPSM6_User_Guide_30Sept14.pdf' introduce you to KCPSM6 and take
you through the creation of a PicoBlaze design. Do take a look at these pages to gain an
appreciation of the PicoBlaze design flow and how to insert and connect KCPSM6 to other
logic but generally ignore anything specifically to do with the ISE tools because you are
using Vivado! The rest of this document provides you with a manual for you to refer to
as you interactively work with PicoBlaze when implementing your own real designs.
Vivado is a relatively new tool and even engineers with years of ISE experience may be
faced with using it for the first time. 'PicoBlaze_Design_in_Vivado' is a supplementary
document that takes one of the reference designs provided in this package and shows you,
step by step, how to create a Vivado project and a way in which you can create and
implement a design containing PicoBlaze. The first page of this document will lead you
to the relevant material depending on your current familiarity with Vivado and PicoBlaze.
When this package was released, Vivado was version 2014.x and ideally you will need to be
using a 2014.x version or later. As you will learn when following the documentation, the
assembler needs a 'ROM_form' template and your default starting template should be renamed
copy of 'ROM_form_JTAGLoader_Vivado_2June14.vhd' or 'ROM_form_JTAGLoader_Vivado_2June14.v'.
Regardless of the design tools you are using, this package also includes the following documents.
Please don't feel that you need to read everything before you start (that wouldn't be fun!), but
do take a look at them when you feel like learning a bit more or feel that you may have an issue.
all_kcpsm6_syntax.psm
Page 52 of 'KCPSM6_User_Guide_30Sept14.pdf' provides a summary of the KCPSM6 Assembler syntax
and pages 53 to 101 show you all the instructions often with snippets of PSM code as examples.
'all_kcpsm6_syntax.psm' is NOT a real program but it does contain valid examples of all PSM
syntax (i.e. it can be assembled). DO LOOK AT THIS file because it provides comprehensive
descriptions of the syntax rules and full details and examples of the assembler directives.
An understanding of the most basic syntax is adequate for most users and applications. However,
there are some quite interesting possibilities that should appeal to anyone that wants to
achieve more with PicoBlaze just have more fun with it!
Known_Issues_and_Workarounds.txt
Ideally you won't encounter any issues, but if you do, please check this one out
and hopefully it will explain what to do.
UART6_User_Guide_and_Reference_Designs_30Sept14.pdf
This document is provided in the 'UART_and_PicoTerm' directory and describes the optimised
UART macros that can be useful in PicoBlaze designs and used in various reference designs.
More designs together with their own documentation can be found in the 'Reference Designs'
directory.
PicoTerm_README.txt
A terminal application called 'PicoTerm' with some rather special, and hopefully fun, features
is also provided in the 'UART_and_PicoTerm' directory.
kcpsm6_assembler_readme.txt
The main documentation should have adequately described how to run the assembler to generate
VHDL, Verliog and HEX file from your PSM code. If you are someone that likes to write batch
files to automate the design flow or you just like to know all the details then this document
is for you.
The remainder of this 'READ_ME_FIRST.txt' file contains the following sections.
- Principle Features of KCPSM6
- System Requirements
- Package Contents
- Changes and Additions in each release.
- Other Useful Stuff?
- Known Limitations
In most cases PicoBlaze design is easy so go and start having fun. Use the rest of this document
for clues should you wonder what something is or need to check the details about package contents
of requirements.
-------------------------------------------------------------------------------------------------
Principle Features of KCPSM6
-------------------------------------------------------------------------------------------------
- Only 26 Slices plus program memory (BRAM).
- 100% embedded solution.
- 8-bit data.
- Performance 52 MIPS to 120 MIPs depending on device family and clock rate.
- Programs up to 4K instructions.
- 32 General Purpose Registers arranged in 2 banks of 16 Registers.
- 256 General Purpose Input Ports.
- 256 General Purpose Output Ports.
- 16 Constant-Optimised Output Ports.
- 64-bytes of scratch pad memory expandable to 128 and 256-bytes (additional 2 and 6 Slices).
- Fully automatic CALL/RETURN stack supporting nested subroutines to 30 levels.
- Interrupt with user definable interrupt vector and maximum response time of 4 clock cycles.
- Power saving features including 'sleep' mode.
- Superset of KCPSM3 with high degree of code compatibility.
- Supplied with optimum UART macros with integral FIFO buffers (only 5 Slices each).
- Reference designs including UART, I2C and SPI communication, control and transactions.
-------------------------------------------------------------------------------------------------
System Requirements
-------------------------------------------------------------------------------------------------
Hardware
--------
KCPSM6 is optimised for Spartan-6, Virtex-6 and 7-Series devices. It also maps well to
UltraScale devices but it can NOT be used with previous generations of device including
Spartan-3 Generation and Virtex-5.
JTAG Loader requires a Platform Cable USB or Digilent equivalent JTAG programming solution.
Note that equivalent circuits are often included on development boards and evaluation kits
rather than as a separate 'pod'.
Xilinx Design Tools
-------------------
ISE - v13.x or later (ideally v14.7).
Please see the 'Known_Issues_and_Workarounds.txt' file if using ISE 12.x.
or
--
Vivado 2014.x or later
Note that JTAG Loader also requires ISE to be installed.
KCPSM6 Assembler
----------------
Windows operating system for KCPSM6 Assembler and JTAG Loader utility.
Users have reported that the KCPSM6 Assembler has worked well with both 32-Bit and 64-bit
versions of both Windows-XP and Win-7 environments. It has also been successfully used with
Wine within a 64-bit Linux environment.
JTAG Loader Utility
-------------------
JTAG Loader makes use of various drivers associated with ChipScope and forming part of an
installation of the ISE tools. Therefore you must have ISE installed (even if using Vivado) and
the 'PATH' and 'XILINX' environment variables must be set appropriately so that JTAG Loader can
locate and use the files that it requires. Below are typical examples of the environment
variables required when using ISE v14.7. It is possible that they have already been set at the
system level but check that they accurately reflect your installation.
PATH = C:\Xilinx\14.7\ISE_DS\ISE\lib\nt; (for 32-bit operating systems)
PATH = C:\Xilinx\14.7\ISE_DS\ISE\lib\nt64; (for 64-bit operating systems)
XILINX = C:\Xilinx\14.7\ISE_DS\ISE
As shown on page 25 of 'KCPSM6_User_Guide_30Sept14.pdf' the 'ISE Design Suite Command Prompt'
can be used or you can manually invoke the 'settings32.bat' or 'settings64.bat' provided in
C:\Xilinx\14.7\ISE_DS (or equivalent depending on version of ISE) once a command window has been
opened.
It is often easier and more convenient to permanently define your PATH and XILINX environment
variables at the system level or to write batch files that temporarily set them before running
JTAG Loader to load a specified program into the memory.
To permanently set 'System Properties'....
Windows XP...
Right click on 'My Computer' and select 'Properties'.
Go to the 'Advanced' tab and choose 'Environment Variables'.
Use 'New' or 'Edit' as necessary.
Windows 7...
Start -> Control Panel -> User Accounts
Change my environment variables
Use 'New' or 'Edit' under 'User variables for <username>' as necessary.
An example batch file (.bat)...
REM Setting environment variables to define location of ISE v14.7
PATH=%PATH%;C:\Xilinx\14.7\ISE_DS\ISE\lib\nt64
set XILINX=C:\Xilinx\14.7\ISE_DS\ISE
REM Upload program HEX using JTAG Loader
JTAG_Loader_Win7_64.exe -l my_program.hex
JTAG Loader must also be able to access some system level DLL files. In the case of a Windows-XP
environment then it is normal for the PATH to contain 'C:\WINDOWS\system32;' or similar. So if
you receive a system error indicating that 'PCMSVCR100.dll' is missing or could not be found then
add the appropriate definition to your PATH. When using a Windows-7 environment it is more likely
that 'MSVCR100.dll' will become the subject of a system error message. 'MSVCR100.dll' is not part
of a default Windows-7 installation but is a often present as a result of a Microsoft Visual C++
application. If you do encounter this issue then the quickest solution is to place a copy of
'msvcr100.dll' provided in the 'JTAG_Loader' directory of this package in to the same directory
as the JTAG Loader executable you are invoking.
-------------------------------------------------------------------------------------------------
Package Contents
-------------------------------------------------------------------------------------------------
READ_ME_FIRST.txt - This file!
KCPSM6_User_Guide_30Sept14.pdf - The main KCPSM6 User Guide document.
Reference_Design_License.pdf - Copy of the Reference Design License Agreement under
which KCPSM6 and the UART macros are released.
PicoBlaze_Design_in_Vivado.pdf - Supplementary guide for Vivado users including the step by
step implementation of one of the reference designs.
Known_Issues_and_Workarounds.txt - List of issues that you may encounter when using KCPSM6.
Please check this file before asking for technical support.
kcpsm6_assembler_readme.txt - Supplementary information related specifically to the KCPSM6
assembler. Describes in detail the options and features when
invoking the assembler from batch files or using the 'drag
and drop' technique.
all_kcpsm6_syntax.psm - Examples and detailed descriptions of all PSM syntax
supported by the KCPSM6 assembler.
kcpsm6.vhd - The KCPSM6 Processor v1.3.
kcpsm6.exe - The KCPSM6 Assembler for Windows v2.70.
ROM_form.vhd - Default program memory template for use during development
when using the ISE tools. Please see 'ROM_form_templates'
below especially when using Vivado (e.g. for UltraScale).
kcpsm6_design_template.vhd - Collection of VHDL reference code for KCPSM6 designs.
-----------------------------------------------------------------------------------
JTAG_Loader - A sub-directory containing JTAG Loader executable files.
Select the executable file corresponding with your operating
system. Please note that for simplicity, the documentation
(e.g. pages 25-29 of 'KCPSM6_User_Guide_29March12.pdf') assume
that the selected executable has been renamed 'jtagloader',
but you can retain the original file name if you prefer.
JTAG_Loader_WinXP_32.exe - Windows-XP 32-Bit.
JTAG_Loader_WinXP_64.exe - Windows-XP 64-Bit.
JTAG_Loader_Win7_32.exe - Windows-7 32-Bit.
JTAG_Loader_Win7_64.exe - Windows-7 64-Bit.
JTAG_Loader_RH_32 - Linux 32-Bit.
JTAG_Loader_RH_64 - Linux 64-Bit.
msvcr100.dll - This DLL is required by JTAG Loader when using
Windows-7 (see 'Requirements' section below).
-----------------------------------------------------------------------------------
ROM_form_templates - A sub-directory containing a copy of the default templates and
optional 'production' templates. Their use is described in
the user guide (see pages 47 and 123) and in assembler
supplement 'kcpsm6_assembler_readme.txt'. Each template file
also includes a description. Note that the Verilog equivalent
of most files is provided in the 'verilog' directory.
ROM_form_JTAGLoader_14March13.vhd - Development template for ISE users only.
Note that the default 'ROM_form.vhd'
template is a renamed copy of this file.
ROM_form_JTAGLoader_3Mar11.vhd - Development template for ISE 12.x users only.
ROM_form_JTAGLoader_Vivado_2June14.vhd - Development template for Vivado users
(UltraScale devices are supported).
ROM_form_S6_1K_5Aug11.vhd - Spartan-6 1K (1 BRAM)
ROM_form_S6_2K_5Aug11.vhd - Spartan-6 2K (2 BRAM)
ROM_form_S6_4K_23Nov12.vhd - Spartan-6 4K (4 BRAM)
ROM_form_V6_1K_14March13.vhd - Virtex-6 1K (0.5 BRAM)
ROM_form_V6_2K_14March13.vhd - Virtex-6 2K (1 BRAM)
ROM_form_V6_4K_14March13.vhd - Virtex-6 4K (2 BRAM)
ROM_form_7S_1K_14March13.vhd - 7-Series 1K (0.5 BRAM)
ROM_form_7S_2K_14March13.vhd - 7-Series 2K (1 BRAM)
ROM_form_7S_4K_14March13.vhd - 7-Series 4K (2 BRAM)
ROM_form_256_5Aug11.vhd - Spartan-6, Virtex-6 and 7-Series
256 instructions (18 Slices)
ROM_form_128_14March13.vhd - Spartan-6, Virtex-6 and 7-Series
128 instructions (9 Slices)
ROM_form_7S_2K_with_error_detection_14March13.vhd - 7-Series 2K (1 BRAM) with
error detection circuit (see User Guide page 118)
ROM_form_7S_1K5_with_ecc_5Dec13.vhd - 7-Series 1.5K (1 BRAM) with error
detection and ECC correction (see User Guide page 119)
-----------------------------------------------------------------------------------
verilog - A sub-directory containing the Verilog equivalent of the
VHDL files to be used in exactly the same way in a design.
kcpsm6.v
ROM_form.v
kcpsm6_design_template.v
ROM_form_JTAGLoader_14March13.v
ROM_form_JTAGLoader_3Mar11.v
ROM_form_JTAGLoader_Vivado_2June14.v
ROM_form_S6_1K_5Aug11.v
ROM_form_S6_2K_5Aug11.v
ROM_form_S6_4K_26Nov12.v
ROM_form_V6_1K_14March13.v
ROM_form_V6_2K_14March13.v
ROM_form_V6_4K_14March13.v
ROM_form_7S_1K_14March13.v
ROM_form_7S_2K_14March13.v
ROM_form_7S_4K_14March13.v
ROM_form_256_5Aug11.v
ROM_form_128_14March13.v
-----------------------------------------------------------------------------------
UART_and_PicoTerm - A sub-directory containing the Ultra-Compact UART macros
together with documentation (readme and PDF), reference designs
and a terminal application (PicoTerm) that is ideally suited
for use with PicoBlaze based designs.
UART6_README.txt
UART6_User_Guide_and_Reference_Designs_29March13.pdf
BAUD_rate_counter_calculator.xlsx
uart_rx6.vhd
uart_tx6.vhd
uart_rx6.v
uart_tx6.v
PicoTerm_README.txt
PicoTerm.exe - PicoTerm v1.97
ML605_design - Reference design presented on ML605 board.
Simple interaction with any terminal.
uart6_ml605.vhd
uart6_ml605.v
uart6_ml605.ucf
uart_control.psm
uart_interface_routines.psm
KC705_design - Reference design presented on KC705 board.
KCPSM6 calculates values to set BAUD rate and
software delays to correspond with clock frequency.
uart6_kc705.vhd
uart6_kc705.v
uart6_kc705.ucf
uart6_kc705.xdc
auto_baud_rate_control.psm
uart_interface_routines.psm
testbench_uart6_kc705.vhd
ATLYS_design - Reference design presented on ATLYS board.
This design also illustrates PicoTerm features.
uart6_atlys.vhd
uart6_atlys.v
uart6_atlys.ucf
atlys_real_time_clock.psm
PicoTerm_routines.psm
soft_delays_100mhz.psm
-----------------------------------------------------------------------------------
Reference_Designs - A sub-directory containing more reference designs that build
on the UART designs listed above and illustrate some typical
KCPSM6 applications. Each design is provided with its own
documentation and source code containing detailed comments.
I2C
Presented on the KC705 Kintex-7 Board this design shows
how KCPSM6 can implement I2C communication. In this example,
KCPSM6 is used to control an I2C Bus Switch (PCA9548) in order
to access the M24C08 EEPROM on the KC705 board. The design can
be used to read and modify any location in the EEPROM.
KC705_KCPSM6_I2C_EEPROM_reference_design.pdf
kc705_kcpsm6_i2c_eeprom.vhd
kc705_kcpsm6_i2c_eeprom.ucf
m24c08_i2c_uart_bridge.psm
i2c_routines.psm
kc705_i2c_devices.psm
soft_delays_100mhz.psm
PicoTerm_routines.psm
SPI
Presented on the KC705 Kintex-7 Board this design shows
how KCPSM6 can implement SPI communication. In this example,
KCPSM6 is used to access the N25Q128 Flash memory whose primary
purpose is holding a configuration image for the Kintex device.
Hence this design can be used to observe a configuration image
as well as erase sectors and write any location.
KC705_KCPSM6_SPI_Flash_reference_design.pdf
kc705_kcpsm6_spi_flash.vhd
kc705_kcpsm6_spi_flash.ucf
n25q128_spi_uart_bridge.psm
N25Q128_SPI_routines.psm
soft_delays_100mhz.psm
PicoTerm_routines.psm
XADC
Presented on the KC705 Kintex-7 Board this design shows
KCPSM6 interfaced to XADC, reading and displaying various
analogue values including a simple plot of die temperature
over time on the PicoTerm Graphic Display
KC705_KCPSM6_XADC_reference_design.pdf
kc705_kcpsm6_xadc.vhd
kc705_kcpsm6_xadc.ucf
xadc_monitor.psm
xadc_routines.psm
soft_delays_200mhz.psm
PicoTerm_routines.psm
ICAP
Presented on the KC705 Kintex-7 Board this design shows
KCPSM6 interfaced to ICAPE2, FRAME_ECCE2 and a BRAM memory.
This design will have particular appeal to anyone interested
in SEU, error detection and correction and the SEM IP core.
ICAPE2 can be used for other applications such as MultiBoot
control so the fundamental communication presented will be
useful for anyone needing to use ICAPE2. The connection of
a BRAM for additional data storage as well as a simple line
editor may have wider appeal to all PicoBlaze users.
KC705_KCPSM6_ICAP_reference_design.pdf
kc705_kcpsm6_icap.vhd
ram_4096x8.vhd
kc705_kcpsm6_icap.xdc
icap_control.psm
ICAPE2_routines.psm
line_input_and_editing.psm
RAM_4096x8_routines.psm
PicoTerm_routines.psm
VC707_KCPSM6_VID_PMBus_and_more.pdf
Additional documentation for the XAPP555 reference design.
This design includes the following KCPSM6 items of interest.
Presented on the VC707 Evaluation Kit
Reading DEVICE_DNA (in this case to extract 'VID')
PMBus control and monitoring of TI Power Controllers
Control of Si570 Programmable Oscillator (I2C and algorithms)
UART macros and communication with user terminal
Internal chain of 1,000 PicoBlaze for control and monitoring!
Measure the power consumption of a PicoBlaze
-----------------------------------------------------------------------------------
Miscellaneous - A sub-directory for miscellaneous files
described in 'Known Issues' where appropriate.
-------------------------------------------------------------------------------------------------
Changes and Additions in each release
-------------------------------------------------------------------------------------------------
Release 1 (30 September 2010)
-----------------------------
Initial public release.
Release 2 (31 March 2011)
-------------------------
kcpsm6.vhd
Correction to logic used to calculate parity (CARRY flag) during a TEST instruction.
The specific conditions under which v1.0 would generate an incorrect result were:-
TEST instruction (not TESTCY).
The least significant 2 bits of the logical AND register had to be "01".
The carry flag had to be set before the TEST instruction was executed.
The most likely coding style in which the defect in v1.0 would be observed would be...
TEST s4, 01
JUMP C, bit0_was_set
Even the above code works in v1.0 if the CARRY flag was clear before the TEST instruction.
Fortunately the most common coding style uses the ZERO flag which works correctly so
the alternative code shown below would work perfectly in v1.0 as well...
TEST s4, 01
JUMP NZ, bit0_was_set
Additions to ROM_form templates.
Mainly additions including support of 7-Series devices but some minor corrections too.
Assembler
Please see 'kcpsm6_assembler_readme.txt' for additions.
User Guide
General additions and corrections.
Verilog equivalent of all VHDL files is now provided.
64-bit version of JTAG_Loader provided in addition to standard version. Physical size of
executable files now much smaller (19KB compared with 468KB).
Release 3 (30 September 2011)
-----------------------------
Adjustments to ROM_form templates to be compatible with with ISE 13.x.
ROM_form templates to support 7-Series devices.
Assembler
Please see 'kcpsm6_assembler_readme.txt' for additions.
User Guide
General additions and corrections.
Optimised UART6 macros provided with reference design and documentation.
Release 4 (30 April 2012)
-------------------------
JTAG Loader
Support for Linux operating system.
Support for Digilent JTAG Programming solution.
Support for spaces in the names of directories in PATH specifications.
Assembler
Addition of an 'INCLUDE' directive.
Support for spaces in the names of directories in PATH specifications.
Enhancements to LOG file contents.
Generation of a 'session log' file.
Please see user guide, 'kcpsm6_assembler_readme.txt' and 'all_kcpsm6_syntax.psm' for details.
UART
Verilog version of the reference design to complement the existing VHDL version.
PSM reference code provides an example of the new INCLUDE directive and is more portable .
PicoTerm v1.03 is provided as a simple terminal ideal for use with PicoBlaze designs.
General additions, enhancements and corrections to all documentation.
Release 5 (30 September 2012)
-----------------------------
Assembler
Enhancements to LOG file contents including instruction and memory usage statistics.
Ability to specify an environment variable in a CONSTANT, STRING or TABLE directive
which in turn provides the value, string or data list. Please see description in
'all_kcpsm6_syntax.psm' for details.
Support for 'ROM_form_7S_2K_with_error_detection_9Aug12.vhd' (see 'Documentation' below).
Examples of 'HWBUILD' instruction added to 'all_kcpsm6_syntax.psm'.
UART
An additional reference design presented on the ATLYS Spartan-6 Design Platform
and exploiting new special features provided in PicoTerm (Hint: Reusable code).
PicoTerm v1.30 includes a Virtual 7-Segment Display, Virtual LEDs and other features
as well as provided the simple terminal ideal for use with PicoBlaze designs.
JTAG Loader
New command line option (-i) can be used to modify the BSCAN 'USER' number.
Please see 'JTAG Loader and BSCAN Users' in the 'Known Issues' section below.
Documentation
A detailed study and discussion concerning KCPSM6 reliability (see pages 106-118 of
'KCPSM6_User_Guide_29March12.pdf'). In addition to the documentation an error detection
scheme has been provided for a 2K program memory in 7-Series devices for those seeking
the very highest levels of design reliability.
General additions, enhancements and corrections to all documentation.
Release 6 (29 March 2013)
-------------------------
Assembler
Enhancements to LOG file and messages relating to PSM syntax.
Pre-defined constants for ASCII control characters
(NUL, BEL, BS, HT, LF, VT, CR, ESC, DEL, DCS, ST).
4K program memory supported in Spartan-6.
128 instruction program memory in 9 Slices for Spartan-6, Virtex-6 and 7-Series.
Improved implementation of 'ROM_form_7S_2K_with_error_detection'.
Unused address inputs on Virtex-6 and 7-Series BRAMs within the 'ROM_form' templates have
been connected High to reflect descriptions in UG363 and UG473 (no functional change).
UART and PicoTerm
PicoTerm v1.72 includes Virtual Switches and a simple Graphic Display.
ATLYS Spartan-6 reference design modified to include PicoTerm Virtual Switches.
Reference Designs
Three new reference designs are presented on the Kintex-7 KC705 board. All build upon the
UART reference designs to show how KCPSM6 can implement...
a) I2C signalling and transactions (I2C Multiplexer control and EEPROM access).
b) SPI signalling and transactions (access Flash memory shared with configuration).
c) an XADC interface and analogue sample value conversions (includes a simple plot of die
temperature over time in the PicoTerm Graphic window).
The source code provided with all designs contains comprehensive descriptions and there is
a supporting PDF document providing an overview, images and schematics.
Documentation
General additions, enhancements and corrections to all documentation.
Release 7 (30 September 2013)
-----------------------------
Assembler
Addition of a 'DEFAULT_JUMP' directive for very high reliability applications.
Correction to handling of TABLEs containing only one item.
UART and PicoTerm
PicoTerm v1.94
Addition of several new DCS commands (see 'PicoTerm_README.txt' for full details)...
'L' and 'l' to open and close a log file.
'R' and 'r' to read files.
'N' to generate and return random numbers.
'p' to return the version of PicoTerm.
Support display of British Pound symbol (<28> = A3 hex).
Improved response to mouse clicks when using the Virtual Switches.
Reference Designs & Documentation
General additions, enhancements and corrections.
Release 8 - 31 March 2014
-------------------------
Assembler
ECC Protected BRAM (1.5K instructions in a 7-Series BRAM).
Enhanced documentation relating to the use of KCPSM6 in high reliability application<6F>s.
LOG file reports contents of unused locations (zero or 'DEFAULT_JUMP' address).
Reference Designs & Documentation
Additions and enhancements to reliability sections (ECC protected program ROM etc).
Supplemental documentation for the XAPP555 reference design.
New in this release (Release 9 - 30 September 2014)
---------------------------------------------------
Documentation
Known issues placed into a separate file called 'Known_Issues_and_Workarounds.txt'.
New document 'PicoBlaze_Design_in_Vivado.pdf' for users of Vivado.
Modified description of 'STAR' instruction.
General additions and corrections.
Hardware
Simulation model added for 'STAR sX, kk' instuction (no logical changes to implementation).
Assembler
Support for the 'STAR sX, kk' instuction.
'ROM_form' templates for use with Vivado (including UltraScale device support).
UART and PicoTerm
'uart6_kc705' reference design provided for the KC705 board and demonstrating a scheme in
which KCPSM6 defines the BAUD rate and software delay loops to reflect the clock frequency.
PicoTerm v1.97
Addition of '-w' command line option to open and write to a log file when opened.
DCS Transaction Window reports opening an closing of log files when DCS commands are used.
'BAUD_rate_counter_calculator.xlsx' spread sheet provided to aid the setting of BAUD rate.
Reference Designs
ICAPE2 design and documentation including Readback CRC monitor and RAM buffer.
-------------------------------------------------------------------------------------------------
Other Useful Stuff?
-------------------------------------------------------------------------------------------------
These links are provided as they may be of interest to KCPSM6 users. Thank you to the people that
have created these tools and have made them available to the PicoBlaze user community.
Please note that these links in no way represent a recommendation of any particular tool or
imply their availability (now or in the future). Should you choose to investigate or work further
with any of these tools then you must evaluate the quality of the offering and you must then
interact with the third party developer of that tool (Xilinx cannot provide support for third
party tools).
Mediatronix Tools
-----------------
http://www.mediatronix.org/pages/Tools
http://code.google.com/p/pblazasm/
pBlazASM is an assembler for PicoBlaze.
pBlazMRG merges code into a VHDL or Verilog template file.
pBlazSIM simulates a KCPSM6.
pBlazDIS can disassemble MEM files and clips from XDL and NDF files.
pBlazBIT can patch Spartan-6 bitstream files directly with MEM and SCR file contents.
FIDEx
-----
http://www.fautronix.com/en/fidex
FIDEx is an integrated assembler development environment (IDE) for soft-core processors and
works on Linux and Windows platforms.
opbasm
------
http://code.google.com/p/opbasm/
Opbasm is a free cross-platform assembler for KCPSM3 and KCPSM6. It will run readily on any
platform with a functional Python intepreter. Opbasm provides a solution to assembling PicoBlaze
code without resorting to DOS or Windows emulation to run the native KCPSM assemblers.
PicoBlaze C Compiler Toolchain 2.1
----------------------------------
http://sp.utia.cz/smecy/pblaze-cc-v2/Users_Guide/index.html#id609572
Optimizing C Compiler and an ELF-Based Toolchain for the PicoBlaze Processor
-------------------------------------------------------------------------------------------------
Known Limitations
-------------------------------------------------------------------------------------------------
DATA2MEM
--------
There are some issues associated with the use of DATA2MEM contained in ISE 12.x and later that
prevent its use in modifying a KCPSM6 program contained in block memory within Spartan-6 and
Virtex-6 devices. It is unlikely that this issue will be fixed but a workaround may yet be
possible to implement. Whenever possible, use JTAG Loader which has the advantage of being much
faster anyway. If you have a requirement to modify more than one KCPSM6 program in the same
design then please contact us to discuss how this may be achieved using JTAG Loader.
DATA2MEM in ISE 14.5 has been used to successfully to modify the contents of a 2K program in a
Kintex-7 device. At this time the procedure is manual and needs to be better documented. Please
contact the author of PicoBlaze if you require early access to this information.
-------------------------------------------------------------------------------------------------
End of file 'READ_ME_FIRST.txt'
-------------------------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,373 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
ROM_form.vhd
Production template for a 0.125K program (128 instructions) for KCPSM6 in a Spartan-6,
Virtex-6 or 7-Series device using 9 Slices.
Ken Chapman (Xilinx Ltd)
14th March 2013 - First Release
This is a VHDL template file for the KCPSM6 assembler.
This VHDL file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.vhd' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the VHDL.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
--
-- Production template for a 0.125K program (128 instructions) for KCPSM6 in a Spartan-6,
-- Virtex-6 or 7-Series device using 9 Slices.
--
-- Note: The full 12-bit KCPSM6 address is connected but only the lower 7-bits will be
-- employed. Likewise the 'bram_enable' should still be connected to 'enable'.
-- This minimises the changes required to the hardware description of a design
-- when moving between different memory types and selecting different sizes.
--
-- program_rom: your_program
-- port map( address => address,
-- instruction => instruction,
-- enable => bram_enable,
-- clk => clk);
--
--
-- Program defined by '{psmname}.psm'.
--
-- Generated by KCPSM6 Assembler: {timestamp}.
--
-- Assembler used ROM_form template: ROM_form_128_14March13.vhd
--
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
--
entity {name} is
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
clk : in std_logic);
end {name};
--
architecture low_level_definition of {name} is
--
signal rom_value : std_logic_vector(17 downto 0);
--
begin
--
instruction_bit: for i in 0 to 17 generate
begin
--
kcpsm6_rom_flop: FDRE
port map ( D => rom_value(i),
Q => instruction(i),
CE => enable,
R => address(7+(i/4)),
C => clk);
--
end generate instruction_bit;
--
--
kcpsm6_rom0: ROM128X1
generic map( INIT => X"{INIT128_0}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(0));
--
kcpsm6_rom1: ROM128X1
generic map( INIT => X"{INIT128_1}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(1));
--
kcpsm6_rom2: ROM128X1
generic map( INIT => X"{INIT128_2}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(2));
--
kcpsm6_rom3: ROM128X1
generic map( INIT => X"{INIT128_3}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(3));
--
kcpsm6_rom4: ROM128X1
generic map( INIT => X"{INIT128_4}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(4));
--
kcpsm6_rom5: ROM128X1
generic map( INIT => X"{INIT128_5}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(5));
--
kcpsm6_rom6: ROM128X1
generic map( INIT => X"{INIT128_6}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(6));
--
kcpsm6_rom7: ROM128X1
generic map( INIT => X"{INIT128_7}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(7));
--
kcpsm6_rom8: ROM128X1
generic map( INIT => X"{INIT128_8}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(8));
--
kcpsm6_rom9: ROM128X1
generic map( INIT => X"{INIT128_9}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(9));
--
kcpsm6_rom10: ROM128X1
generic map( INIT => X"{INIT128_10}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(10));
--
kcpsm6_rom11: ROM128X1
generic map( INIT => X"{INIT128_11}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(11));
--
kcpsm6_rom12: ROM128X1
generic map( INIT => X"{INIT128_12}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(12));
--
kcpsm6_rom13: ROM128X1
generic map( INIT => X"{INIT128_13}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(13));
--
kcpsm6_rom14: ROM128X1
generic map( INIT => X"{INIT128_14}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(14));
--
kcpsm6_rom15: ROM128X1
generic map( INIT => X"{INIT128_15}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(15));
--
kcpsm6_rom16: ROM128X1
generic map( INIT => X"{INIT128_16}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(16));
--
kcpsm6_rom17: ROM128X1
generic map( INIT => X"{INIT128_17}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
O => rom_value(17));
--
--
end low_level_definition;
--
------------------------------------------------------------------------------------
--
-- END OF FILE {name}.vhd
--
------------------------------------------------------------------------------------

View File

@ -0,0 +1,388 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2011, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
ROM_form.vhd
Production template for a 0.25K program (256 instructions) for KCPSM6 in a Spartan-6,
Virtex-6 or 7-Series device using 18 Slices.
Ken Chapman (Xilinx Ltd)
5th August 2011
This is a VHDL template file for the KCPSM6 assembler.
This VHDL file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.vhd' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the VHDL.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2011, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
--
-- Production definition of a 0.25K program (256 instructions) for KCPSM6 in a Spartan-6,
-- Virtex-6 or 7-Series device device using 18 Slices.
--
-- Note: The full 12-bit KCPSM6 address is connected but only the lower 8-bits will be
-- employed. Likewise the 'bram_enable' should still be connected to 'enable'.
-- This minimises the changes required to the hardware description of a design
-- when moving between different memory types and selecting different sizes.
--
-- program_rom: your_program
-- port map( address => address,
-- instruction => instruction,
-- enable => bram_enable,
-- clk => clk);
--
--
-- Program defined by '{psmname}.psm'.
--
-- Generated by KCPSM6 Assembler: {timestamp}.
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
--
entity {name} is
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
clk : in std_logic);
end {name};
--
architecture low_level_definition of {name} is
--
signal rom_value : std_logic_vector(17 downto 0);
--
begin
--
instruction_bit: for i in 0 to 17 generate
begin
--
kcpsm6_rom_flop: FDRE
port map ( D => rom_value(i),
Q => instruction(i),
CE => enable,
R => address(8+(i/5)),
C => clk);
--
end generate instruction_bit;
--
--
kcpsm6_rom0: ROM256X1
generic map( INIT => X"{INIT256_0}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(0));
--
kcpsm6_rom1: ROM256X1
generic map( INIT => X"{INIT256_1}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(1));
--
kcpsm6_rom2: ROM256X1
generic map( INIT => X"{INIT256_2}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(2));
--
kcpsm6_rom3: ROM256X1
generic map( INIT => X"{INIT256_3}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(3));
--
kcpsm6_rom4: ROM256X1
generic map( INIT => X"{INIT256_4}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(4));
--
kcpsm6_rom5: ROM256X1
generic map( INIT => X"{INIT256_5}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(5));
--
kcpsm6_rom6: ROM256X1
generic map( INIT => X"{INIT256_6}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(6));
--
kcpsm6_rom7: ROM256X1
generic map( INIT => X"{INIT256_7}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(7));
--
kcpsm6_rom8: ROM256X1
generic map( INIT => X"{INIT256_8}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(8));
--
kcpsm6_rom9: ROM256X1
generic map( INIT => X"{INIT256_9}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(9));
--
kcpsm6_rom10: ROM256X1
generic map( INIT => X"{INIT256_10}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(10));
--
kcpsm6_rom11: ROM256X1
generic map( INIT => X"{INIT256_11}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(11));
--
kcpsm6_rom12: ROM256X1
generic map( INIT => X"{INIT256_12}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(12));
--
kcpsm6_rom13: ROM256X1
generic map( INIT => X"{INIT256_13}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(13));
--
kcpsm6_rom14: ROM256X1
generic map( INIT => X"{INIT256_14}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(14));
--
kcpsm6_rom15: ROM256X1
generic map( INIT => X"{INIT256_15}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(15));
--
kcpsm6_rom16: ROM256X1
generic map( INIT => X"{INIT256_16}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(16));
--
kcpsm6_rom17: ROM256X1
generic map( INIT => X"{INIT256_17}")
port map( A0 => address(0),
A1 => address(1),
A2 => address(2),
A3 => address(3),
A4 => address(4),
A5 => address(5),
A6 => address(6),
A7 => address(7),
O => rom_value(17));
--
--
end low_level_definition;
--
------------------------------------------------------------------------------------
--
-- END OF FILE {name}.vhd
--
------------------------------------------------------------------------------------

View File

@ -0,0 +1,594 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
ROM_form.vhd
Production template for a 1.5K program (address range 000 to 5FF) for KCPSM6 in a 7-Series
device using a RAMB36E1 primitive with built-in Error Correcting Code (ECC) and 4.5 Slices.
PLEASE READ THE DESCRIPTIONS AND ADVICE LATER IN THIS TEMPLATE OR CONTAINED IN THE
ASSEMBLED FILE.
Ken Chapman (Xilinx Ltd)
5th December 2013 - Initial Release
This is a VHDL template file for the KCPSM6 assembler.
This VHDL file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.vhd' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the VHDL.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
-- Program defined by '{psmname}.psm'.
--
-- Generated by KCPSM6 Assembler: {timestamp}.
--
-- Assembler used ROM_form template: ROM_form_7S_1K5_with_ecc_5Dec13.vhd
--
--
-- Production definition of a 1.5K program (address range 000 to 5FF) for KCPSM6 in a
-- 7-Series device using a RAMB36E1 primitive with built-in Error Correcting Code (ECC)
-- and 4.5 Slices.
--
-- NOTE - Compared with any of the normal program memory definitions for KCPSM6 this
-- module has additional outputs associated with the error detection and
-- correction feature. Only use this module if there is a clear requirement to
-- perform error detection and correction and do consider all the factors
-- described below before incorporating it in a design.
--
-- The built-in ECC feature can only be used when the RAMB36E1 primitive is
-- configured to be 64 data bits wide plus 8 'parity' (ECC) bits. At this aspect
-- ratio the memory has 512 locations. In this KCPSM6 program memory, three
-- 18-bit instructions are packed into each 64-bit word resulting in the somewhat
-- unusual program size of 1.5K instructions. So please be very aware that the
-- address range is (000 to 5FF) as that is not a power of two!
--
-- When the built-in ECC feature is used, the clock to output time of the
-- RAMB36E1 is also increased. Furthermore, a multiplexer is then required to
-- select the required instruction from the three presented in each 64-bit word
-- which also increases the time taken for the instruction to reach KCPSM6. Hence
-- the maximum clock frequency that can be achieved when using this ECC protected
-- memory will be less than when using any of the standard memories. If highest
-- performance is critical to your application then...
-- i) Reconsider if error correction is really required.
-- ii) Consider using the program memory with CRC error detection only.
-- iii) The 'sleep' mode could be used to run KCPSM6 at a lower rate whilst
-- remaining synchronous the higher clock rate (see 'Slow down waveforms' on
-- page 39 of the 'KCPSM6_User_Guide'). One or more additional clock cycles
-- would then be available to read the ECC protected memory. Hint: You will
-- need to permanently enable the memory (i.e. tie 'enable' High) and
-- define a multi-cycle timing constraint to cover the path from the
-- program memory to KCPSM6. Adding a pipeline stage in the instruction
-- path would also be possible when using the slow down technique.
--
-- Error Detection and Correction Features
-- ---------------------------------------
--
-- In this application the BRAM is being used as a ROM and therefore the contents should
-- not change during normal operation. If for any reason the contents of the memory should
-- change then there is the potential for KCPSM6 to execute an instruction that is either
-- different to that expected or even an invalid op-code neither of which would be
-- desirable. Obviously this should not happen and in majority of cases it will be more
-- than acceptable to assume that it never will. However, designs in which extreme levels
-- of reliability are required may consider that the special error detection and correction
-- features provided in this memory definition are useful.
--
-- This memory uses the built-in Error Correcting Code (ECC) feature of the RAMB36E1
-- primitive. This requires that the memory is configured to be 512 locations each
-- containing a 64-bit data word and an 8-bit ECC. 'address[8:0]' from KCPM6 is supplied
-- directly to the RAMB36E1 primitive and reads a 64-bit word containing three 18-bit
-- instructions (i.e. 54-bits are actually used). A single bit error anywhere in the
-- 64-bit word or the 8-bit ECC value will be detected and corrected by the built-in
-- logic. 'address[10:9]' from KCPM6 is then used (via a pipeline compensation register)
-- to select the required instruction from the three presented.
--
-- The arrangement means that the three instructions packed into each memory location
-- are from different 'blocks' of the program address range.
--
-- BRAM Data Bits Instruction from address address [8:0]
-- KCPSM6 Address Range [11:9]
--
-- [57:40] 400 to 5FF 010 000000000 - 111111111
-- [37:20] 200 to 3FF 001 000000000 - 111111111
-- [17:0] 000 to 1FF 000 000000000 - 111111111
--
-- The ECC scheme can correct any single bit errors which, although rare, are the most
-- likely to occur. In the unlikely event that a double bit error should occur (in the
-- same 64+8 bits) then the ECC scheme will report its detection even though it can not
-- correct. The 'SBITERR' and 'DBITERR' status signals from the built-in ECC decoder and
-- correction logic are presented as outputs of this memory. In most cases 'SBITERR' can
-- be ignored but it is always interesting to log events (e.g. how often did KCPSM6
-- benefit from using this feature?). 'DBITERR' could mean that KCPSM6 has be presented
-- with a corrupted instruction so it would probably be time to perform some further
-- checks and/or mitigation at the system level.
--
-- Note - If a double bit error is detected and reported then there is a 75% probability
-- that is did not corrupt the instruction that KCPSM6 actually used (i.e. the
-- instruction used is only 18-bits out of the 72-bits read from the memory). At
-- the time that this particular KCPSM6 program memory was developed there were
-- ideas to implement an enhanced scheme capable of refining the error reporting
-- to only the instruction being selected. Please check to see if this scheme is
-- now available for your consideration.
--
--
-- SEU Mitigation
-- --------------
--
-- One concern for the very highest reliability systems are Single Event Upsets (SEU)
-- caused by radiation. FIT rates for BRAM are published and updated quarterly in UG116
-- and these should be used to evaluate the potential failure rates prior to using this
-- memory with its error detection and correction features.
--
-- UG116 (v9.6) published 19th November 2013 shows that the real time soft error rate for
-- Block RAM memory in a 7-Series device is 78 FIT/Mb. Based on this figure (you should
-- always use the latest version of UG116 in your own calculations), the nominal upset
-- rate for contents of this one RAMB36E1 (36kbits) is 1.44 FIT. That's equivalent to one
-- upset inside this memory every 79,274 years when operating at sea-level New York. Even
-- when flying at an altitude of 40,000ft anywhere around the world the upset rate would
-- be 158 years (and aircraft don't fly for that long!).
--
-- The analysis shows that it is most unlikely that multiple events would lead to the
-- accumulation of bit errors within the same KCPSM6 program memory. Even if two events
-- did lead to two upsets it is statistically unlikely (1 in 512) that they would both
-- occur in the same 64+8 bit location and hence the ECC scheme would be able to detect
-- and correct the single bit errors contained in any of the instructions as they were
-- being read.
--
-- Note - When an error is detected, it is only the word read from the memory is corrected.
-- The contents of the memory remain the same so any error will be detected and
-- corrected every time the same location is accessed. Hence the 'SBITERR' would be
-- seen to pulse High every time KCPSM6 accessed the memory location containing the
-- error. Hence, multiple 'SBITERR' pulses do NOT mean there are multiple errors.
-- It would be possible to implement a memory write-back or 'scrubbing' mechanism
-- but with such a low probability of multiple events leading to the accumulation
-- of errors such a scheme was considered to be unnecessary.
--
--
-- Mitigation of incorrect program execution using 'DEFAULT_JUMP' Directive
-- ------------------------------------------------------------------------
--
-- Even with an ECC protected program memory there is the possibility of an SEU impacting
-- the operation of KCPSM6 (i.e. an SEU flips a configuration cell that impacts either the
-- logic or interconnect associated with KCPSM6). There is also the potential for a PSM
-- program to be incorrect in some way (i.e. we all make mistakes!). As such, it is
-- possible that KCPSM6 could at some time attempt to fetch an instruction from an address
-- outside of the available memory range 000 to 5FF hex.
--
-- This memory will detect any address in the range 600 to FFF hex and force the 18-bit
-- instruction to be a predictable fixed value. The KCPSM6 Assembler supports a directive
-- called 'DEFAULT_JUMP' which is described in 'all_kcpsm6_syntax.psm'. This directive
-- is normally used to fill all otherwise unused locations in a memory with a 'JUMP'
-- instruction to a address defined by the user. The user would typically define a special
-- routine at this location to handle the otherwise unexpected case. When 'DEFAULT_JUMP'
-- is used with this memory it will fill all otherwise unused locations in the usual way
-- but it will also define the output instruction in the address range 600 to FFF hex.
--
-- Hint - In the interest of achieving maximum reliability it is recommended that the
-- 'DEFAULT_JUMP' directive be used. If it is not used then this memory will still
-- detect any address in the range 600 to FFF hex and force the output instruction
-- to '00000' equivalent to 'LOAD s0, s0' which is a 'no-operation' (which is also
-- the default for any unused locations in any program memory).
--
--
-- TESTING METHODS
-- ---------------
--
-- The error correction capability can be tested by deliberately corrupting any bit stored
-- in the memory by manually adjusting one of the INIT values before processing the design.
-- Then observe the SBITERR and DBITERR outputs when KCPSM6 fetches the corrupted word from
-- the memory.
--
-- Hints - Each hexadecimal digit in an INIT string represents 4 adjacent bits in the
-- same 64-bit word (or 8-bit ECC) read from the memory so only adjust a digit
-- in a way that would create a single bit error or an adjacent double bit error
-- (e.g. 'E' hex = 1110 binary so 'A' hex would be the single bit error 1010 but
-- '0' hex would be a 3-bit error 0000 and an unrealistic test case).
--
-- SBITERR or DBITERR will pulse when KCPSM6 reads a word from memory containing
-- an error. Each word is associated with three addresses in different 'blocks'
-- (see above). So consider where you locate the error and how your PSM program
-- will execute because each error relates to three addresses.
--
-- Single bit errors are corrected so KCPSM6 execution should always continue
-- to be correct when SBITERR pulses are observed. If a double bit error is
-- created and DBITERR pulse is observed then the instruction fetched could be
-- corrupted depending on where you created the error.
--
-- Each 64-bit word contains three 18-bit instructions and ten otherwise unused
-- bits (bits 18, 19, 38, 39, 58, 59, 60, 61, 62, 62 and 63). Errors created in
-- these unused bits will still result in SBITERR or DBITERR pulses but we
-- would know that all three instructions remain valid. Hence these are good
-- places to create double bit errors for test purposes.
--
-- With due care and attention paid to the fact that each 64-bit word contains
-- three instructions from different blocks, your PSM code could contain a test
-- routine located at a particular address range corresponding with the location
-- of the deliberate errors created in the INIT strings. In this way SBITERR and
-- DBITERR could be made to pulse when required for test purposes but normal
-- operation would never execute any of the instructions contained in the
-- corrupted word(s).
--
--
-------------------------------------------------------------------------------------------
--
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
--
entity {name} is
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
SBITERR : out std_logic;
DBITERR : out std_logic;
clk : in std_logic);
end {name};
--
architecture low_level_definition of {name} is
--
signal address_a : std_logic_vector(15 downto 0);
signal address_b : std_logic_vector(15 downto 0);
signal data_in : std_logic_vector(63 downto 0);
signal data_out : std_logic_vector(63 downto 0);
signal data_in_p : std_logic_vector(7 downto 0);
--
signal pipe_address : std_logic_vector(11 downto 9);
--
--
constant default_jump : std_logic_vector(17 downto 0) := "{default_jump}";
--
--
begin
--
address_a <= '1' & address(8 downto 0) & "111111";
address_b <= "1111111111111111";
data_in <= data_out(63 downto 58) & "000000000000000000" & data_out(39 downto 38) & "000000000000000000" & data_out(19 downto 18)& "000000000000000000";
data_in_p <= "00000000";
--
kcpsm6_rom: RAMB36E1
generic map ( READ_WIDTH_A => 72,
WRITE_WIDTH_A => 0,
DOA_REG => 0,
INIT_A => X"000000000",
RSTREG_PRIORITY_A => "REGCE",
SRVAL_A => X"000000000",
WRITE_MODE_A => "WRITE_FIRST",
READ_WIDTH_B => 0,
WRITE_WIDTH_B => 72,
DOB_REG => 0,
INIT_B => X"000000000",
RSTREG_PRIORITY_B => "REGCE",
SRVAL_B => X"000000000",
WRITE_MODE_B => "WRITE_FIRST",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
RAM_MODE => "SDP",
RDADDR_COLLISION_HWCONFIG => "DELAYED_WRITE",
EN_ECC_READ => TRUE,
EN_ECC_WRITE => FALSE,
RAM_EXTENSION_A => "NONE",
RAM_EXTENSION_B => "NONE",
SIM_DEVICE => "7SERIES",
INIT_00 => X"{ECC_7S_1K5_INIT_00}",
INIT_01 => X"{ECC_7S_1K5_INIT_01}",
INIT_02 => X"{ECC_7S_1K5_INIT_02}",
INIT_03 => X"{ECC_7S_1K5_INIT_03}",
INIT_04 => X"{ECC_7S_1K5_INIT_04}",
INIT_05 => X"{ECC_7S_1K5_INIT_05}",
INIT_06 => X"{ECC_7S_1K5_INIT_06}",
INIT_07 => X"{ECC_7S_1K5_INIT_07}",
INIT_08 => X"{ECC_7S_1K5_INIT_08}",
INIT_09 => X"{ECC_7S_1K5_INIT_09}",
INIT_0A => X"{ECC_7S_1K5_INIT_0A}",
INIT_0B => X"{ECC_7S_1K5_INIT_0B}",
INIT_0C => X"{ECC_7S_1K5_INIT_0C}",
INIT_0D => X"{ECC_7S_1K5_INIT_0D}",
INIT_0E => X"{ECC_7S_1K5_INIT_0E}",
INIT_0F => X"{ECC_7S_1K5_INIT_0F}",
INIT_10 => X"{ECC_7S_1K5_INIT_10}",
INIT_11 => X"{ECC_7S_1K5_INIT_11}",
INIT_12 => X"{ECC_7S_1K5_INIT_12}",
INIT_13 => X"{ECC_7S_1K5_INIT_13}",
INIT_14 => X"{ECC_7S_1K5_INIT_14}",
INIT_15 => X"{ECC_7S_1K5_INIT_15}",
INIT_16 => X"{ECC_7S_1K5_INIT_16}",
INIT_17 => X"{ECC_7S_1K5_INIT_17}",
INIT_18 => X"{ECC_7S_1K5_INIT_18}",
INIT_19 => X"{ECC_7S_1K5_INIT_19}",
INIT_1A => X"{ECC_7S_1K5_INIT_1A}",
INIT_1B => X"{ECC_7S_1K5_INIT_1B}",
INIT_1C => X"{ECC_7S_1K5_INIT_1C}",
INIT_1D => X"{ECC_7S_1K5_INIT_1D}",
INIT_1E => X"{ECC_7S_1K5_INIT_1E}",
INIT_1F => X"{ECC_7S_1K5_INIT_1F}",
INIT_20 => X"{ECC_7S_1K5_INIT_20}",
INIT_21 => X"{ECC_7S_1K5_INIT_21}",
INIT_22 => X"{ECC_7S_1K5_INIT_22}",
INIT_23 => X"{ECC_7S_1K5_INIT_23}",
INIT_24 => X"{ECC_7S_1K5_INIT_24}",
INIT_25 => X"{ECC_7S_1K5_INIT_25}",
INIT_26 => X"{ECC_7S_1K5_INIT_26}",
INIT_27 => X"{ECC_7S_1K5_INIT_27}",
INIT_28 => X"{ECC_7S_1K5_INIT_28}",
INIT_29 => X"{ECC_7S_1K5_INIT_29}",
INIT_2A => X"{ECC_7S_1K5_INIT_2A}",
INIT_2B => X"{ECC_7S_1K5_INIT_2B}",
INIT_2C => X"{ECC_7S_1K5_INIT_2C}",
INIT_2D => X"{ECC_7S_1K5_INIT_2D}",
INIT_2E => X"{ECC_7S_1K5_INIT_2E}",
INIT_2F => X"{ECC_7S_1K5_INIT_2F}",
INIT_30 => X"{ECC_7S_1K5_INIT_30}",
INIT_31 => X"{ECC_7S_1K5_INIT_31}",
INIT_32 => X"{ECC_7S_1K5_INIT_32}",
INIT_33 => X"{ECC_7S_1K5_INIT_33}",
INIT_34 => X"{ECC_7S_1K5_INIT_34}",
INIT_35 => X"{ECC_7S_1K5_INIT_35}",
INIT_36 => X"{ECC_7S_1K5_INIT_36}",
INIT_37 => X"{ECC_7S_1K5_INIT_37}",
INIT_38 => X"{ECC_7S_1K5_INIT_38}",
INIT_39 => X"{ECC_7S_1K5_INIT_39}",
INIT_3A => X"{ECC_7S_1K5_INIT_3A}",
INIT_3B => X"{ECC_7S_1K5_INIT_3B}",
INIT_3C => X"{ECC_7S_1K5_INIT_3C}",
INIT_3D => X"{ECC_7S_1K5_INIT_3D}",
INIT_3E => X"{ECC_7S_1K5_INIT_3E}",
INIT_3F => X"{ECC_7S_1K5_INIT_3F}",
INIT_40 => X"{ECC_7S_1K5_INIT_40}",
INIT_41 => X"{ECC_7S_1K5_INIT_41}",
INIT_42 => X"{ECC_7S_1K5_INIT_42}",
INIT_43 => X"{ECC_7S_1K5_INIT_43}",
INIT_44 => X"{ECC_7S_1K5_INIT_44}",
INIT_45 => X"{ECC_7S_1K5_INIT_45}",
INIT_46 => X"{ECC_7S_1K5_INIT_46}",
INIT_47 => X"{ECC_7S_1K5_INIT_47}",
INIT_48 => X"{ECC_7S_1K5_INIT_48}",
INIT_49 => X"{ECC_7S_1K5_INIT_49}",
INIT_4A => X"{ECC_7S_1K5_INIT_4A}",
INIT_4B => X"{ECC_7S_1K5_INIT_4B}",
INIT_4C => X"{ECC_7S_1K5_INIT_4C}",
INIT_4D => X"{ECC_7S_1K5_INIT_4D}",
INIT_4E => X"{ECC_7S_1K5_INIT_4E}",
INIT_4F => X"{ECC_7S_1K5_INIT_4F}",
INIT_50 => X"{ECC_7S_1K5_INIT_50}",
INIT_51 => X"{ECC_7S_1K5_INIT_51}",
INIT_52 => X"{ECC_7S_1K5_INIT_52}",
INIT_53 => X"{ECC_7S_1K5_INIT_53}",
INIT_54 => X"{ECC_7S_1K5_INIT_54}",
INIT_55 => X"{ECC_7S_1K5_INIT_55}",
INIT_56 => X"{ECC_7S_1K5_INIT_56}",
INIT_57 => X"{ECC_7S_1K5_INIT_57}",
INIT_58 => X"{ECC_7S_1K5_INIT_58}",
INIT_59 => X"{ECC_7S_1K5_INIT_59}",
INIT_5A => X"{ECC_7S_1K5_INIT_5A}",
INIT_5B => X"{ECC_7S_1K5_INIT_5B}",
INIT_5C => X"{ECC_7S_1K5_INIT_5C}",
INIT_5D => X"{ECC_7S_1K5_INIT_5D}",
INIT_5E => X"{ECC_7S_1K5_INIT_5E}",
INIT_5F => X"{ECC_7S_1K5_INIT_5F}",
INIT_60 => X"{ECC_7S_1K5_INIT_60}",
INIT_61 => X"{ECC_7S_1K5_INIT_61}",
INIT_62 => X"{ECC_7S_1K5_INIT_62}",
INIT_63 => X"{ECC_7S_1K5_INIT_63}",
INIT_64 => X"{ECC_7S_1K5_INIT_64}",
INIT_65 => X"{ECC_7S_1K5_INIT_65}",
INIT_66 => X"{ECC_7S_1K5_INIT_66}",
INIT_67 => X"{ECC_7S_1K5_INIT_67}",
INIT_68 => X"{ECC_7S_1K5_INIT_68}",
INIT_69 => X"{ECC_7S_1K5_INIT_69}",
INIT_6A => X"{ECC_7S_1K5_INIT_6A}",
INIT_6B => X"{ECC_7S_1K5_INIT_6B}",
INIT_6C => X"{ECC_7S_1K5_INIT_6C}",
INIT_6D => X"{ECC_7S_1K5_INIT_6D}",
INIT_6E => X"{ECC_7S_1K5_INIT_6E}",
INIT_6F => X"{ECC_7S_1K5_INIT_6F}",
INIT_70 => X"{ECC_7S_1K5_INIT_70}",
INIT_71 => X"{ECC_7S_1K5_INIT_71}",
INIT_72 => X"{ECC_7S_1K5_INIT_72}",
INIT_73 => X"{ECC_7S_1K5_INIT_73}",
INIT_74 => X"{ECC_7S_1K5_INIT_74}",
INIT_75 => X"{ECC_7S_1K5_INIT_75}",
INIT_76 => X"{ECC_7S_1K5_INIT_76}",
INIT_77 => X"{ECC_7S_1K5_INIT_77}",
INIT_78 => X"{ECC_7S_1K5_INIT_78}",
INIT_79 => X"{ECC_7S_1K5_INIT_79}",
INIT_7A => X"{ECC_7S_1K5_INIT_7A}",
INIT_7B => X"{ECC_7S_1K5_INIT_7B}",
INIT_7C => X"{ECC_7S_1K5_INIT_7C}",
INIT_7D => X"{ECC_7S_1K5_INIT_7D}",
INIT_7E => X"{ECC_7S_1K5_INIT_7E}",
INIT_7F => X"{ECC_7S_1K5_INIT_7F}",
INITP_00 => X"{ECC_7S_1K5_INITP_00}",
INITP_01 => X"{ECC_7S_1K5_INITP_01}",
INITP_02 => X"{ECC_7S_1K5_INITP_02}",
INITP_03 => X"{ECC_7S_1K5_INITP_03}",
INITP_04 => X"{ECC_7S_1K5_INITP_04}",
INITP_05 => X"{ECC_7S_1K5_INITP_05}",
INITP_06 => X"{ECC_7S_1K5_INITP_06}",
INITP_07 => X"{ECC_7S_1K5_INITP_07}",
INITP_08 => X"{ECC_7S_1K5_INITP_08}",
INITP_09 => X"{ECC_7S_1K5_INITP_09}",
INITP_0A => X"{ECC_7S_1K5_INITP_0A}",
INITP_0B => X"{ECC_7S_1K5_INITP_0B}",
INITP_0C => X"{ECC_7S_1K5_INITP_0C}",
INITP_0D => X"{ECC_7S_1K5_INITP_0D}",
INITP_0E => X"{ECC_7S_1K5_INITP_0E}",
INITP_0F => X"{ECC_7S_1K5_INITP_0F}")
port map( ADDRARDADDR => address_a,
ENARDEN => enable,
CLKARDCLK => clk,
DOADO => data_out(31 downto 0),
DIADI => data_in(31 downto 0),
DIPADIP => data_in_p(3 downto 0),
WEA => "0000",
REGCEAREGCE => '0',
RSTRAMARSTRAM => '0',
RSTREGARSTREG => '0',
ADDRBWRADDR => address_b,
ENBWREN => '0',
CLKBWRCLK => '0',
DOBDO => data_out(63 downto 32),
DIBDI => data_in(63 downto 32),
DIPBDIP => data_in_p(7 downto 4),
WEBWE => "00000000",
REGCEB => '0',
RSTRAMB => '0',
RSTREGB => '0',
CASCADEINA => '0',
CASCADEINB => '0',
SBITERR => SBITERR,
DBITERR => DBITERR,
INJECTDBITERR => '0',
INJECTSBITERR => '0');
--
pipe_address_loop: for i in 9 to 11 generate
begin
--
kcpsm6_rom_flop: FDE
port map ( D => address(i),
Q => pipe_address(i),
CE => enable,
C => clk);
--
end generate pipe_address_loop;
--
instruction_width_loop: for i in 0 to 17 generate
begin
--
force_low: if default_jump(i)='0' generate
begin
--
kcpsm6_rom_lut: LUT6
generic map (INIT => X"0000000000F0CCAA")
port map( I0 => data_out(i),
I1 => data_out(i+20),
I2 => data_out(i+40),
I3 => pipe_address(9),
I4 => pipe_address(10),
I5 => pipe_address(11),
O => instruction(i));
--
end generate force_low;
--
force_high: if default_jump(i)='1' generate
begin
--
kcpsm6_rom_lut: LUT6
generic map (INIT => X"FFFFFFFFFFF0CCAA")
port map( I0 => data_out(i),
I1 => data_out(i+20),
I2 => data_out(i+40),
I3 => pipe_address(9),
I4 => pipe_address(10),
I5 => pipe_address(11),
O => instruction(i));
--
end generate force_high;
--
end generate instruction_width_loop;
--
end low_level_definition;
--
------------------------------------------------------------------------------------
--
-- END OF FILE {name}.vhd
--
------------------------------------------------------------------------------------

View File

@ -0,0 +1,293 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
ROM_form.vhd
Production template for a 1K program for KCPSM6 in a 7-Series device using a
RAMB18E1 primitive.
Ken Chapman (Xilinx Ltd)
5th August 2011 - First Release
14th March 2013 - Unused address inputs on BRAMs connected High to reflect
descriptions UG473.
This is a VHDL template file for the KCPSM6 assembler.
This VHDL file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.vhd' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the VHDL.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
--
-- Production definition of a 1K program for KCPSM6 in a 7-Series device using a
-- RAMB18E1 primitive.
--
-- Note: The complete 12-bit address bus is connected to KCPSM6 to facilitate future code
-- expansion with minimum changes being required to the hardware description.
-- Only the lower 10-bits of the address are actually used for the 1K address range
-- 000 to 3FF hex.
--
-- Program defined by '{psmname}.psm'.
--
-- Generated by KCPSM6 Assembler: {timestamp}.
--
-- Assembler used ROM_form template: ROM_form_7S_1K_14March13.vhd
--
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
--
entity {name} is
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
clk : in std_logic);
end {name};
--
architecture low_level_definition of {name} is
--
signal address_a : std_logic_vector(13 downto 0);
signal data_in_a : std_logic_vector(17 downto 0);
signal data_out_a : std_logic_vector(17 downto 0);
signal address_b : std_logic_vector(13 downto 0);
signal data_in_b : std_logic_vector(17 downto 0);
signal data_out_b : std_logic_vector(17 downto 0);
signal enable_b : std_logic;
signal clk_b : std_logic;
signal we_b : std_logic_vector(3 downto 0);
--
begin
--
address_a <= address(9 downto 0) & "1111";
instruction <= data_out_a(17 downto 0);
data_in_a <= "0000000000000000" & address(11 downto 10);
--
address_b <= "11111111111111";
data_in_b <= data_out_b(17 downto 0);
enable_b <= '0';
we_b <= "0000";
clk_b <= '0';
--
--
--
kcpsm6_rom: RAMB18E1
generic map ( READ_WIDTH_A => 18,
WRITE_WIDTH_A => 18,
DOA_REG => 0,
INIT_A => "000000000000000000",
RSTREG_PRIORITY_A => "REGCE",
SRVAL_A => X"000000000000000000",
WRITE_MODE_A => "WRITE_FIRST",
READ_WIDTH_B => 18,
WRITE_WIDTH_B => 18,
DOB_REG => 0,
INIT_B => X"000000000000000000",
RSTREG_PRIORITY_B => "REGCE",
SRVAL_B => X"000000000000000000",
WRITE_MODE_B => "WRITE_FIRST",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
RAM_MODE => "TDP",
RDADDR_COLLISION_HWCONFIG => "DELAYED_WRITE",
SIM_DEVICE => "7SERIES",
INIT_00 => X"{INIT_00}",
INIT_01 => X"{INIT_01}",
INIT_02 => X"{INIT_02}",
INIT_03 => X"{INIT_03}",
INIT_04 => X"{INIT_04}",
INIT_05 => X"{INIT_05}",
INIT_06 => X"{INIT_06}",
INIT_07 => X"{INIT_07}",
INIT_08 => X"{INIT_08}",
INIT_09 => X"{INIT_09}",
INIT_0A => X"{INIT_0A}",
INIT_0B => X"{INIT_0B}",
INIT_0C => X"{INIT_0C}",
INIT_0D => X"{INIT_0D}",
INIT_0E => X"{INIT_0E}",
INIT_0F => X"{INIT_0F}",
INIT_10 => X"{INIT_10}",
INIT_11 => X"{INIT_11}",
INIT_12 => X"{INIT_12}",
INIT_13 => X"{INIT_13}",
INIT_14 => X"{INIT_14}",
INIT_15 => X"{INIT_15}",
INIT_16 => X"{INIT_16}",
INIT_17 => X"{INIT_17}",
INIT_18 => X"{INIT_18}",
INIT_19 => X"{INIT_19}",
INIT_1A => X"{INIT_1A}",
INIT_1B => X"{INIT_1B}",
INIT_1C => X"{INIT_1C}",
INIT_1D => X"{INIT_1D}",
INIT_1E => X"{INIT_1E}",
INIT_1F => X"{INIT_1F}",
INIT_20 => X"{INIT_20}",
INIT_21 => X"{INIT_21}",
INIT_22 => X"{INIT_22}",
INIT_23 => X"{INIT_23}",
INIT_24 => X"{INIT_24}",
INIT_25 => X"{INIT_25}",
INIT_26 => X"{INIT_26}",
INIT_27 => X"{INIT_27}",
INIT_28 => X"{INIT_28}",
INIT_29 => X"{INIT_29}",
INIT_2A => X"{INIT_2A}",
INIT_2B => X"{INIT_2B}",
INIT_2C => X"{INIT_2C}",
INIT_2D => X"{INIT_2D}",
INIT_2E => X"{INIT_2E}",
INIT_2F => X"{INIT_2F}",
INIT_30 => X"{INIT_30}",
INIT_31 => X"{INIT_31}",
INIT_32 => X"{INIT_32}",
INIT_33 => X"{INIT_33}",
INIT_34 => X"{INIT_34}",
INIT_35 => X"{INIT_35}",
INIT_36 => X"{INIT_36}",
INIT_37 => X"{INIT_37}",
INIT_38 => X"{INIT_38}",
INIT_39 => X"{INIT_39}",
INIT_3A => X"{INIT_3A}",
INIT_3B => X"{INIT_3B}",
INIT_3C => X"{INIT_3C}",
INIT_3D => X"{INIT_3D}",
INIT_3E => X"{INIT_3E}",
INIT_3F => X"{INIT_3F}",
INITP_00 => X"{INITP_00}",
INITP_01 => X"{INITP_01}",
INITP_02 => X"{INITP_02}",
INITP_03 => X"{INITP_03}",
INITP_04 => X"{INITP_04}",
INITP_05 => X"{INITP_05}",
INITP_06 => X"{INITP_06}",
INITP_07 => X"{INITP_07}")
port map( ADDRARDADDR => address_a,
ENARDEN => enable,
CLKARDCLK => clk,
DOADO => data_out_a(15 downto 0),
DOPADOP => data_out_a(17 downto 16),
DIADI => data_in_a(15 downto 0),
DIPADIP => data_in_a(17 downto 16),
WEA => "00",
REGCEAREGCE => '0',
RSTRAMARSTRAM => '0',
RSTREGARSTREG => '0',
ADDRBWRADDR => address_b,
ENBWREN => enable_b,
CLKBWRCLK => clk_b,
DOBDO => data_out_b(15 downto 0),
DOPBDOP => data_out_b(17 downto 16),
DIBDI => data_in_b(15 downto 0),
DIPBDIP => data_in_b(17 downto 16),
WEBWE => we_b,
REGCEB => '0',
RSTRAMB => '0',
RSTREGB => '0');
--
--
end low_level_definition;
--
------------------------------------------------------------------------------------
--
-- END OF FILE {name}.vhd
--
------------------------------------------------------------------------------------

View File

@ -0,0 +1,370 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
ROM_form.vhd
Production template for a 2K program for KCPSM6 in a 7-Series device using a
RAMB36E1 primitive.
Ken Chapman (Xilinx Ltd)
5th August 2011 - First Release
14th March 2013 - Unused address inputs on BRAMs connected High to reflect
descriptions UG473.
This is a VHDL template file for the KCPSM6 assembler.
This VHDL file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.vhd' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the VHDL.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
--
-- Production definition of a 2K program for KCPSM6 in a 7-Series device using a
-- RAMB36E1 primitive.
--
-- Note: The complete 12-bit address bus is connected to KCPSM6 to facilitate future code
-- expansion with minimum changes being required to the hardware description.
-- Only the lower 11-bits of the address are actually used for the 2K address range
-- 000 to 7FF hex.
--
-- Program defined by '{psmname}.psm'.
--
-- Generated by KCPSM6 Assembler: {timestamp}.
--
-- Assembler used ROM_form template: ROM_form_7S_2K_14March13.vhd
--
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
--
entity {name} is
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
clk : in std_logic);
end {name};
--
architecture low_level_definition of {name} is
--
signal address_a : std_logic_vector(15 downto 0);
signal data_in_a : std_logic_vector(35 downto 0);
signal data_out_a : std_logic_vector(35 downto 0);
signal address_b : std_logic_vector(15 downto 0);
signal data_in_b : std_logic_vector(35 downto 0);
signal data_out_b : std_logic_vector(35 downto 0);
signal enable_b : std_logic;
signal clk_b : std_logic;
signal we_b : std_logic_vector(7 downto 0);
--
begin
--
address_a <= '1' & address(10 downto 0) & "1111";
instruction <= data_out_a(33 downto 32) & data_out_a(15 downto 0);
data_in_a <= "00000000000000000000000000000000000" & address(11);
--
address_b <= "1111111111111111";
data_in_b <= "00" & data_out_b(33 downto 32) & "0000000000000000" & data_out_b(15 downto 0);
enable_b <= '0';
we_b <= "00000000";
clk_b <= '0';
--
kcpsm6_rom: RAMB36E1
generic map ( READ_WIDTH_A => 18,
WRITE_WIDTH_A => 18,
DOA_REG => 0,
INIT_A => X"000000000",
RSTREG_PRIORITY_A => "REGCE",
SRVAL_A => X"000000000",
WRITE_MODE_A => "WRITE_FIRST",
READ_WIDTH_B => 18,
WRITE_WIDTH_B => 18,
DOB_REG => 0,
INIT_B => X"000000000",
RSTREG_PRIORITY_B => "REGCE",
SRVAL_B => X"000000000",
WRITE_MODE_B => "WRITE_FIRST",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
RAM_MODE => "TDP",
RDADDR_COLLISION_HWCONFIG => "DELAYED_WRITE",
EN_ECC_READ => FALSE,
EN_ECC_WRITE => FALSE,
RAM_EXTENSION_A => "NONE",
RAM_EXTENSION_B => "NONE",
SIM_DEVICE => "7SERIES",
INIT_00 => X"{INIT_00}",
INIT_01 => X"{INIT_01}",
INIT_02 => X"{INIT_02}",
INIT_03 => X"{INIT_03}",
INIT_04 => X"{INIT_04}",
INIT_05 => X"{INIT_05}",
INIT_06 => X"{INIT_06}",
INIT_07 => X"{INIT_07}",
INIT_08 => X"{INIT_08}",
INIT_09 => X"{INIT_09}",
INIT_0A => X"{INIT_0A}",
INIT_0B => X"{INIT_0B}",
INIT_0C => X"{INIT_0C}",
INIT_0D => X"{INIT_0D}",
INIT_0E => X"{INIT_0E}",
INIT_0F => X"{INIT_0F}",
INIT_10 => X"{INIT_10}",
INIT_11 => X"{INIT_11}",
INIT_12 => X"{INIT_12}",
INIT_13 => X"{INIT_13}",
INIT_14 => X"{INIT_14}",
INIT_15 => X"{INIT_15}",
INIT_16 => X"{INIT_16}",
INIT_17 => X"{INIT_17}",
INIT_18 => X"{INIT_18}",
INIT_19 => X"{INIT_19}",
INIT_1A => X"{INIT_1A}",
INIT_1B => X"{INIT_1B}",
INIT_1C => X"{INIT_1C}",
INIT_1D => X"{INIT_1D}",
INIT_1E => X"{INIT_1E}",
INIT_1F => X"{INIT_1F}",
INIT_20 => X"{INIT_20}",
INIT_21 => X"{INIT_21}",
INIT_22 => X"{INIT_22}",
INIT_23 => X"{INIT_23}",
INIT_24 => X"{INIT_24}",
INIT_25 => X"{INIT_25}",
INIT_26 => X"{INIT_26}",
INIT_27 => X"{INIT_27}",
INIT_28 => X"{INIT_28}",
INIT_29 => X"{INIT_29}",
INIT_2A => X"{INIT_2A}",
INIT_2B => X"{INIT_2B}",
INIT_2C => X"{INIT_2C}",
INIT_2D => X"{INIT_2D}",
INIT_2E => X"{INIT_2E}",
INIT_2F => X"{INIT_2F}",
INIT_30 => X"{INIT_30}",
INIT_31 => X"{INIT_31}",
INIT_32 => X"{INIT_32}",
INIT_33 => X"{INIT_33}",
INIT_34 => X"{INIT_34}",
INIT_35 => X"{INIT_35}",
INIT_36 => X"{INIT_36}",
INIT_37 => X"{INIT_37}",
INIT_38 => X"{INIT_38}",
INIT_39 => X"{INIT_39}",
INIT_3A => X"{INIT_3A}",
INIT_3B => X"{INIT_3B}",
INIT_3C => X"{INIT_3C}",
INIT_3D => X"{INIT_3D}",
INIT_3E => X"{INIT_3E}",
INIT_3F => X"{INIT_3F}",
INIT_40 => X"{INIT_40}",
INIT_41 => X"{INIT_41}",
INIT_42 => X"{INIT_42}",
INIT_43 => X"{INIT_43}",
INIT_44 => X"{INIT_44}",
INIT_45 => X"{INIT_45}",
INIT_46 => X"{INIT_46}",
INIT_47 => X"{INIT_47}",
INIT_48 => X"{INIT_48}",
INIT_49 => X"{INIT_49}",
INIT_4A => X"{INIT_4A}",
INIT_4B => X"{INIT_4B}",
INIT_4C => X"{INIT_4C}",
INIT_4D => X"{INIT_4D}",
INIT_4E => X"{INIT_4E}",
INIT_4F => X"{INIT_4F}",
INIT_50 => X"{INIT_50}",
INIT_51 => X"{INIT_51}",
INIT_52 => X"{INIT_52}",
INIT_53 => X"{INIT_53}",
INIT_54 => X"{INIT_54}",
INIT_55 => X"{INIT_55}",
INIT_56 => X"{INIT_56}",
INIT_57 => X"{INIT_57}",
INIT_58 => X"{INIT_58}",
INIT_59 => X"{INIT_59}",
INIT_5A => X"{INIT_5A}",
INIT_5B => X"{INIT_5B}",
INIT_5C => X"{INIT_5C}",
INIT_5D => X"{INIT_5D}",
INIT_5E => X"{INIT_5E}",
INIT_5F => X"{INIT_5F}",
INIT_60 => X"{INIT_60}",
INIT_61 => X"{INIT_61}",
INIT_62 => X"{INIT_62}",
INIT_63 => X"{INIT_63}",
INIT_64 => X"{INIT_64}",
INIT_65 => X"{INIT_65}",
INIT_66 => X"{INIT_66}",
INIT_67 => X"{INIT_67}",
INIT_68 => X"{INIT_68}",
INIT_69 => X"{INIT_69}",
INIT_6A => X"{INIT_6A}",
INIT_6B => X"{INIT_6B}",
INIT_6C => X"{INIT_6C}",
INIT_6D => X"{INIT_6D}",
INIT_6E => X"{INIT_6E}",
INIT_6F => X"{INIT_6F}",
INIT_70 => X"{INIT_70}",
INIT_71 => X"{INIT_71}",
INIT_72 => X"{INIT_72}",
INIT_73 => X"{INIT_73}",
INIT_74 => X"{INIT_74}",
INIT_75 => X"{INIT_75}",
INIT_76 => X"{INIT_76}",
INIT_77 => X"{INIT_77}",
INIT_78 => X"{INIT_78}",
INIT_79 => X"{INIT_79}",
INIT_7A => X"{INIT_7A}",
INIT_7B => X"{INIT_7B}",
INIT_7C => X"{INIT_7C}",
INIT_7D => X"{INIT_7D}",
INIT_7E => X"{INIT_7E}",
INIT_7F => X"{INIT_7F}",
INITP_00 => X"{INITP_00}",
INITP_01 => X"{INITP_01}",
INITP_02 => X"{INITP_02}",
INITP_03 => X"{INITP_03}",
INITP_04 => X"{INITP_04}",
INITP_05 => X"{INITP_05}",
INITP_06 => X"{INITP_06}",
INITP_07 => X"{INITP_07}",
INITP_08 => X"{INITP_08}",
INITP_09 => X"{INITP_09}",
INITP_0A => X"{INITP_0A}",
INITP_0B => X"{INITP_0B}",
INITP_0C => X"{INITP_0C}",
INITP_0D => X"{INITP_0D}",
INITP_0E => X"{INITP_0E}",
INITP_0F => X"{INITP_0F}")
port map( ADDRARDADDR => address_a,
ENARDEN => enable,
CLKARDCLK => clk,
DOADO => data_out_a(31 downto 0),
DOPADOP => data_out_a(35 downto 32),
DIADI => data_in_a(31 downto 0),
DIPADIP => data_in_a(35 downto 32),
WEA => "0000",
REGCEAREGCE => '0',
RSTRAMARSTRAM => '0',
RSTREGARSTREG => '0',
ADDRBWRADDR => address_b,
ENBWREN => enable_b,
CLKBWRCLK => clk_b,
DOBDO => data_out_b(31 downto 0),
DOPBDOP => data_out_b(35 downto 32),
DIBDI => data_in_b(31 downto 0),
DIPBDIP => data_in_b(35 downto 32),
WEBWE => we_b,
REGCEB => '0',
RSTRAMB => '0',
RSTREGB => '0',
CASCADEINA => '0',
CASCADEINB => '0',
INJECTDBITERR => '0',
INJECTSBITERR => '0');
--
--
end low_level_definition;
--
------------------------------------------------------------------------------------
--
-- END OF FILE {name}.vhd
--
------------------------------------------------------------------------------------

View File

@ -0,0 +1,564 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
ROM_form.vhd
Production template for a 4K program for KCPSM6 in a 7-Series device using
2 x RAMB36E1 primitives.
Ken Chapman (Xilinx Ltd)
5th August 2011 - First Release
14th March 2013 - Unused address inputs on BRAMs connected High to reflect
descriptions UG473.
This is a VHDL template file for the KCPSM6 assembler.
This VHDL file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.vhd' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the VHDL.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
--
-- Production definition of a 4K program for KCPSM6 in a 7-Series device using
-- 2 x RAMB36E1 primitives.
--
--
-- Program defined by '{psmname}.psm'.
--
-- Generated by KCPSM6 Assembler: {timestamp}.
--
-- Assembler used ROM_form template: ROM_form_7S_4K_14March13.vhd
--
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
--
entity {name} is
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
clk : in std_logic);
end {name};
--
architecture low_level_definition of {name} is
--
signal address_a : std_logic_vector(15 downto 0);
signal data_in_a : std_logic_vector(35 downto 0);
signal data_out_a_l : std_logic_vector(35 downto 0);
signal data_out_a_h : std_logic_vector(35 downto 0);
signal address_b : std_logic_vector(15 downto 0);
signal data_in_b_l : std_logic_vector(35 downto 0);
signal data_out_b_l : std_logic_vector(35 downto 0);
signal data_in_b_h : std_logic_vector(35 downto 0);
signal data_out_b_h : std_logic_vector(35 downto 0);
signal enable_b : std_logic;
signal clk_b : std_logic;
signal we_b : std_logic_vector(7 downto 0);
--
begin
--
address_a <= '1' & address(11 downto 0) & "111";
instruction <= data_out_a_h(32) & data_out_a_h(7 downto 0) & data_out_a_l(32) & data_out_a_l(7 downto 0);
data_in_a <= "000000000000000000000000000000000000";
--
address_b <= "1111111111111111";
data_in_b_l <= "000" & data_out_b_l(32) & "000000000000000000000000" & data_out_b_l(7 downto 0);
data_in_b_h <= "000" & data_out_b_h(32) & "000000000000000000000000" & data_out_b_h(7 downto 0);
enable_b <= '0';
we_b <= "00000000";
clk_b <= '0';
--
kcpsm6_rom_l: RAMB36E1
generic map ( READ_WIDTH_A => 9,
WRITE_WIDTH_A => 9,
DOA_REG => 0,
INIT_A => X"000000000",
RSTREG_PRIORITY_A => "REGCE",
SRVAL_A => X"000000000",
WRITE_MODE_A => "WRITE_FIRST",
READ_WIDTH_B => 9,
WRITE_WIDTH_B => 9,
DOB_REG => 0,
INIT_B => X"000000000",
RSTREG_PRIORITY_B => "REGCE",
SRVAL_B => X"000000000",
WRITE_MODE_B => "WRITE_FIRST",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
RAM_MODE => "TDP",
RDADDR_COLLISION_HWCONFIG => "DELAYED_WRITE",
EN_ECC_READ => FALSE,
EN_ECC_WRITE => FALSE,
RAM_EXTENSION_A => "NONE",
RAM_EXTENSION_B => "NONE",
SIM_DEVICE => "7SERIES",
INIT_00 => X"{[8:0]_INIT_00}",
INIT_01 => X"{[8:0]_INIT_01}",
INIT_02 => X"{[8:0]_INIT_02}",
INIT_03 => X"{[8:0]_INIT_03}",
INIT_04 => X"{[8:0]_INIT_04}",
INIT_05 => X"{[8:0]_INIT_05}",
INIT_06 => X"{[8:0]_INIT_06}",
INIT_07 => X"{[8:0]_INIT_07}",
INIT_08 => X"{[8:0]_INIT_08}",
INIT_09 => X"{[8:0]_INIT_09}",
INIT_0A => X"{[8:0]_INIT_0A}",
INIT_0B => X"{[8:0]_INIT_0B}",
INIT_0C => X"{[8:0]_INIT_0C}",
INIT_0D => X"{[8:0]_INIT_0D}",
INIT_0E => X"{[8:0]_INIT_0E}",
INIT_0F => X"{[8:0]_INIT_0F}",
INIT_10 => X"{[8:0]_INIT_10}",
INIT_11 => X"{[8:0]_INIT_11}",
INIT_12 => X"{[8:0]_INIT_12}",
INIT_13 => X"{[8:0]_INIT_13}",
INIT_14 => X"{[8:0]_INIT_14}",
INIT_15 => X"{[8:0]_INIT_15}",
INIT_16 => X"{[8:0]_INIT_16}",
INIT_17 => X"{[8:0]_INIT_17}",
INIT_18 => X"{[8:0]_INIT_18}",
INIT_19 => X"{[8:0]_INIT_19}",
INIT_1A => X"{[8:0]_INIT_1A}",
INIT_1B => X"{[8:0]_INIT_1B}",
INIT_1C => X"{[8:0]_INIT_1C}",
INIT_1D => X"{[8:0]_INIT_1D}",
INIT_1E => X"{[8:0]_INIT_1E}",
INIT_1F => X"{[8:0]_INIT_1F}",
INIT_20 => X"{[8:0]_INIT_20}",
INIT_21 => X"{[8:0]_INIT_21}",
INIT_22 => X"{[8:0]_INIT_22}",
INIT_23 => X"{[8:0]_INIT_23}",
INIT_24 => X"{[8:0]_INIT_24}",
INIT_25 => X"{[8:0]_INIT_25}",
INIT_26 => X"{[8:0]_INIT_26}",
INIT_27 => X"{[8:0]_INIT_27}",
INIT_28 => X"{[8:0]_INIT_28}",
INIT_29 => X"{[8:0]_INIT_29}",
INIT_2A => X"{[8:0]_INIT_2A}",
INIT_2B => X"{[8:0]_INIT_2B}",
INIT_2C => X"{[8:0]_INIT_2C}",
INIT_2D => X"{[8:0]_INIT_2D}",
INIT_2E => X"{[8:0]_INIT_2E}",
INIT_2F => X"{[8:0]_INIT_2F}",
INIT_30 => X"{[8:0]_INIT_30}",
INIT_31 => X"{[8:0]_INIT_31}",
INIT_32 => X"{[8:0]_INIT_32}",
INIT_33 => X"{[8:0]_INIT_33}",
INIT_34 => X"{[8:0]_INIT_34}",
INIT_35 => X"{[8:0]_INIT_35}",
INIT_36 => X"{[8:0]_INIT_36}",
INIT_37 => X"{[8:0]_INIT_37}",
INIT_38 => X"{[8:0]_INIT_38}",
INIT_39 => X"{[8:0]_INIT_39}",
INIT_3A => X"{[8:0]_INIT_3A}",
INIT_3B => X"{[8:0]_INIT_3B}",
INIT_3C => X"{[8:0]_INIT_3C}",
INIT_3D => X"{[8:0]_INIT_3D}",
INIT_3E => X"{[8:0]_INIT_3E}",
INIT_3F => X"{[8:0]_INIT_3F}",
INIT_40 => X"{[8:0]_INIT_40}",
INIT_41 => X"{[8:0]_INIT_41}",
INIT_42 => X"{[8:0]_INIT_42}",
INIT_43 => X"{[8:0]_INIT_43}",
INIT_44 => X"{[8:0]_INIT_44}",
INIT_45 => X"{[8:0]_INIT_45}",
INIT_46 => X"{[8:0]_INIT_46}",
INIT_47 => X"{[8:0]_INIT_47}",
INIT_48 => X"{[8:0]_INIT_48}",
INIT_49 => X"{[8:0]_INIT_49}",
INIT_4A => X"{[8:0]_INIT_4A}",
INIT_4B => X"{[8:0]_INIT_4B}",
INIT_4C => X"{[8:0]_INIT_4C}",
INIT_4D => X"{[8:0]_INIT_4D}",
INIT_4E => X"{[8:0]_INIT_4E}",
INIT_4F => X"{[8:0]_INIT_4F}",
INIT_50 => X"{[8:0]_INIT_50}",
INIT_51 => X"{[8:0]_INIT_51}",
INIT_52 => X"{[8:0]_INIT_52}",
INIT_53 => X"{[8:0]_INIT_53}",
INIT_54 => X"{[8:0]_INIT_54}",
INIT_55 => X"{[8:0]_INIT_55}",
INIT_56 => X"{[8:0]_INIT_56}",
INIT_57 => X"{[8:0]_INIT_57}",
INIT_58 => X"{[8:0]_INIT_58}",
INIT_59 => X"{[8:0]_INIT_59}",
INIT_5A => X"{[8:0]_INIT_5A}",
INIT_5B => X"{[8:0]_INIT_5B}",
INIT_5C => X"{[8:0]_INIT_5C}",
INIT_5D => X"{[8:0]_INIT_5D}",
INIT_5E => X"{[8:0]_INIT_5E}",
INIT_5F => X"{[8:0]_INIT_5F}",
INIT_60 => X"{[8:0]_INIT_60}",
INIT_61 => X"{[8:0]_INIT_61}",
INIT_62 => X"{[8:0]_INIT_62}",
INIT_63 => X"{[8:0]_INIT_63}",
INIT_64 => X"{[8:0]_INIT_64}",
INIT_65 => X"{[8:0]_INIT_65}",
INIT_66 => X"{[8:0]_INIT_66}",
INIT_67 => X"{[8:0]_INIT_67}",
INIT_68 => X"{[8:0]_INIT_68}",
INIT_69 => X"{[8:0]_INIT_69}",
INIT_6A => X"{[8:0]_INIT_6A}",
INIT_6B => X"{[8:0]_INIT_6B}",
INIT_6C => X"{[8:0]_INIT_6C}",
INIT_6D => X"{[8:0]_INIT_6D}",
INIT_6E => X"{[8:0]_INIT_6E}",
INIT_6F => X"{[8:0]_INIT_6F}",
INIT_70 => X"{[8:0]_INIT_70}",
INIT_71 => X"{[8:0]_INIT_71}",
INIT_72 => X"{[8:0]_INIT_72}",
INIT_73 => X"{[8:0]_INIT_73}",
INIT_74 => X"{[8:0]_INIT_74}",
INIT_75 => X"{[8:0]_INIT_75}",
INIT_76 => X"{[8:0]_INIT_76}",
INIT_77 => X"{[8:0]_INIT_77}",
INIT_78 => X"{[8:0]_INIT_78}",
INIT_79 => X"{[8:0]_INIT_79}",
INIT_7A => X"{[8:0]_INIT_7A}",
INIT_7B => X"{[8:0]_INIT_7B}",
INIT_7C => X"{[8:0]_INIT_7C}",
INIT_7D => X"{[8:0]_INIT_7D}",
INIT_7E => X"{[8:0]_INIT_7E}",
INIT_7F => X"{[8:0]_INIT_7F}",
INITP_00 => X"{[8:0]_INITP_00}",
INITP_01 => X"{[8:0]_INITP_01}",
INITP_02 => X"{[8:0]_INITP_02}",
INITP_03 => X"{[8:0]_INITP_03}",
INITP_04 => X"{[8:0]_INITP_04}",
INITP_05 => X"{[8:0]_INITP_05}",
INITP_06 => X"{[8:0]_INITP_06}",
INITP_07 => X"{[8:0]_INITP_07}",
INITP_08 => X"{[8:0]_INITP_08}",
INITP_09 => X"{[8:0]_INITP_09}",
INITP_0A => X"{[8:0]_INITP_0A}",
INITP_0B => X"{[8:0]_INITP_0B}",
INITP_0C => X"{[8:0]_INITP_0C}",
INITP_0D => X"{[8:0]_INITP_0D}",
INITP_0E => X"{[8:0]_INITP_0E}",
INITP_0F => X"{[8:0]_INITP_0F}")
port map( ADDRARDADDR => address_a,
ENARDEN => enable,
CLKARDCLK => clk,
DOADO => data_out_a_l(31 downto 0),
DOPADOP => data_out_a_l(35 downto 32),
DIADI => data_in_a(31 downto 0),
DIPADIP => data_in_a(35 downto 32),
WEA => "0000",
REGCEAREGCE => '0',
RSTRAMARSTRAM => '0',
RSTREGARSTREG => '0',
ADDRBWRADDR => address_b,
ENBWREN => enable_b,
CLKBWRCLK => clk_b,
DOBDO => data_out_b_l(31 downto 0),
DOPBDOP => data_out_b_l(35 downto 32),
DIBDI => data_in_b_l(31 downto 0),
DIPBDIP => data_in_b_l(35 downto 32),
WEBWE => we_b,
REGCEB => '0',
RSTRAMB => '0',
RSTREGB => '0',
CASCADEINA => '0',
CASCADEINB => '0',
INJECTDBITERR => '0',
INJECTSBITERR => '0');
--
kcpsm6_rom_h: RAMB36E1
generic map ( READ_WIDTH_A => 9,
WRITE_WIDTH_A => 9,
DOA_REG => 0,
INIT_A => X"000000000",
RSTREG_PRIORITY_A => "REGCE",
SRVAL_A => X"000000000",
WRITE_MODE_A => "WRITE_FIRST",
READ_WIDTH_B => 9,
WRITE_WIDTH_B => 9,
DOB_REG => 0,
INIT_B => X"000000000",
RSTREG_PRIORITY_B => "REGCE",
SRVAL_B => X"000000000",
WRITE_MODE_B => "WRITE_FIRST",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
RAM_MODE => "TDP",
RDADDR_COLLISION_HWCONFIG => "DELAYED_WRITE",
EN_ECC_READ => FALSE,
EN_ECC_WRITE => FALSE,
RAM_EXTENSION_A => "NONE",
RAM_EXTENSION_B => "NONE",
SIM_DEVICE => "7SERIES",
INIT_00 => X"{[17:9]_INIT_00}",
INIT_01 => X"{[17:9]_INIT_01}",
INIT_02 => X"{[17:9]_INIT_02}",
INIT_03 => X"{[17:9]_INIT_03}",
INIT_04 => X"{[17:9]_INIT_04}",
INIT_05 => X"{[17:9]_INIT_05}",
INIT_06 => X"{[17:9]_INIT_06}",
INIT_07 => X"{[17:9]_INIT_07}",
INIT_08 => X"{[17:9]_INIT_08}",
INIT_09 => X"{[17:9]_INIT_09}",
INIT_0A => X"{[17:9]_INIT_0A}",
INIT_0B => X"{[17:9]_INIT_0B}",
INIT_0C => X"{[17:9]_INIT_0C}",
INIT_0D => X"{[17:9]_INIT_0D}",
INIT_0E => X"{[17:9]_INIT_0E}",
INIT_0F => X"{[17:9]_INIT_0F}",
INIT_10 => X"{[17:9]_INIT_10}",
INIT_11 => X"{[17:9]_INIT_11}",
INIT_12 => X"{[17:9]_INIT_12}",
INIT_13 => X"{[17:9]_INIT_13}",
INIT_14 => X"{[17:9]_INIT_14}",
INIT_15 => X"{[17:9]_INIT_15}",
INIT_16 => X"{[17:9]_INIT_16}",
INIT_17 => X"{[17:9]_INIT_17}",
INIT_18 => X"{[17:9]_INIT_18}",
INIT_19 => X"{[17:9]_INIT_19}",
INIT_1A => X"{[17:9]_INIT_1A}",
INIT_1B => X"{[17:9]_INIT_1B}",
INIT_1C => X"{[17:9]_INIT_1C}",
INIT_1D => X"{[17:9]_INIT_1D}",
INIT_1E => X"{[17:9]_INIT_1E}",
INIT_1F => X"{[17:9]_INIT_1F}",
INIT_20 => X"{[17:9]_INIT_20}",
INIT_21 => X"{[17:9]_INIT_21}",
INIT_22 => X"{[17:9]_INIT_22}",
INIT_23 => X"{[17:9]_INIT_23}",
INIT_24 => X"{[17:9]_INIT_24}",
INIT_25 => X"{[17:9]_INIT_25}",
INIT_26 => X"{[17:9]_INIT_26}",
INIT_27 => X"{[17:9]_INIT_27}",
INIT_28 => X"{[17:9]_INIT_28}",
INIT_29 => X"{[17:9]_INIT_29}",
INIT_2A => X"{[17:9]_INIT_2A}",
INIT_2B => X"{[17:9]_INIT_2B}",
INIT_2C => X"{[17:9]_INIT_2C}",
INIT_2D => X"{[17:9]_INIT_2D}",
INIT_2E => X"{[17:9]_INIT_2E}",
INIT_2F => X"{[17:9]_INIT_2F}",
INIT_30 => X"{[17:9]_INIT_30}",
INIT_31 => X"{[17:9]_INIT_31}",
INIT_32 => X"{[17:9]_INIT_32}",
INIT_33 => X"{[17:9]_INIT_33}",
INIT_34 => X"{[17:9]_INIT_34}",
INIT_35 => X"{[17:9]_INIT_35}",
INIT_36 => X"{[17:9]_INIT_36}",
INIT_37 => X"{[17:9]_INIT_37}",
INIT_38 => X"{[17:9]_INIT_38}",
INIT_39 => X"{[17:9]_INIT_39}",
INIT_3A => X"{[17:9]_INIT_3A}",
INIT_3B => X"{[17:9]_INIT_3B}",
INIT_3C => X"{[17:9]_INIT_3C}",
INIT_3D => X"{[17:9]_INIT_3D}",
INIT_3E => X"{[17:9]_INIT_3E}",
INIT_3F => X"{[17:9]_INIT_3F}",
INIT_40 => X"{[17:9]_INIT_40}",
INIT_41 => X"{[17:9]_INIT_41}",
INIT_42 => X"{[17:9]_INIT_42}",
INIT_43 => X"{[17:9]_INIT_43}",
INIT_44 => X"{[17:9]_INIT_44}",
INIT_45 => X"{[17:9]_INIT_45}",
INIT_46 => X"{[17:9]_INIT_46}",
INIT_47 => X"{[17:9]_INIT_47}",
INIT_48 => X"{[17:9]_INIT_48}",
INIT_49 => X"{[17:9]_INIT_49}",
INIT_4A => X"{[17:9]_INIT_4A}",
INIT_4B => X"{[17:9]_INIT_4B}",
INIT_4C => X"{[17:9]_INIT_4C}",
INIT_4D => X"{[17:9]_INIT_4D}",
INIT_4E => X"{[17:9]_INIT_4E}",
INIT_4F => X"{[17:9]_INIT_4F}",
INIT_50 => X"{[17:9]_INIT_50}",
INIT_51 => X"{[17:9]_INIT_51}",
INIT_52 => X"{[17:9]_INIT_52}",
INIT_53 => X"{[17:9]_INIT_53}",
INIT_54 => X"{[17:9]_INIT_54}",
INIT_55 => X"{[17:9]_INIT_55}",
INIT_56 => X"{[17:9]_INIT_56}",
INIT_57 => X"{[17:9]_INIT_57}",
INIT_58 => X"{[17:9]_INIT_58}",
INIT_59 => X"{[17:9]_INIT_59}",
INIT_5A => X"{[17:9]_INIT_5A}",
INIT_5B => X"{[17:9]_INIT_5B}",
INIT_5C => X"{[17:9]_INIT_5C}",
INIT_5D => X"{[17:9]_INIT_5D}",
INIT_5E => X"{[17:9]_INIT_5E}",
INIT_5F => X"{[17:9]_INIT_5F}",
INIT_60 => X"{[17:9]_INIT_60}",
INIT_61 => X"{[17:9]_INIT_61}",
INIT_62 => X"{[17:9]_INIT_62}",
INIT_63 => X"{[17:9]_INIT_63}",
INIT_64 => X"{[17:9]_INIT_64}",
INIT_65 => X"{[17:9]_INIT_65}",
INIT_66 => X"{[17:9]_INIT_66}",
INIT_67 => X"{[17:9]_INIT_67}",
INIT_68 => X"{[17:9]_INIT_68}",
INIT_69 => X"{[17:9]_INIT_69}",
INIT_6A => X"{[17:9]_INIT_6A}",
INIT_6B => X"{[17:9]_INIT_6B}",
INIT_6C => X"{[17:9]_INIT_6C}",
INIT_6D => X"{[17:9]_INIT_6D}",
INIT_6E => X"{[17:9]_INIT_6E}",
INIT_6F => X"{[17:9]_INIT_6F}",
INIT_70 => X"{[17:9]_INIT_70}",
INIT_71 => X"{[17:9]_INIT_71}",
INIT_72 => X"{[17:9]_INIT_72}",
INIT_73 => X"{[17:9]_INIT_73}",
INIT_74 => X"{[17:9]_INIT_74}",
INIT_75 => X"{[17:9]_INIT_75}",
INIT_76 => X"{[17:9]_INIT_76}",
INIT_77 => X"{[17:9]_INIT_77}",
INIT_78 => X"{[17:9]_INIT_78}",
INIT_79 => X"{[17:9]_INIT_79}",
INIT_7A => X"{[17:9]_INIT_7A}",
INIT_7B => X"{[17:9]_INIT_7B}",
INIT_7C => X"{[17:9]_INIT_7C}",
INIT_7D => X"{[17:9]_INIT_7D}",
INIT_7E => X"{[17:9]_INIT_7E}",
INIT_7F => X"{[17:9]_INIT_7F}",
INITP_00 => X"{[17:9]_INITP_00}",
INITP_01 => X"{[17:9]_INITP_01}",
INITP_02 => X"{[17:9]_INITP_02}",
INITP_03 => X"{[17:9]_INITP_03}",
INITP_04 => X"{[17:9]_INITP_04}",
INITP_05 => X"{[17:9]_INITP_05}",
INITP_06 => X"{[17:9]_INITP_06}",
INITP_07 => X"{[17:9]_INITP_07}",
INITP_08 => X"{[17:9]_INITP_08}",
INITP_09 => X"{[17:9]_INITP_09}",
INITP_0A => X"{[17:9]_INITP_0A}",
INITP_0B => X"{[17:9]_INITP_0B}",
INITP_0C => X"{[17:9]_INITP_0C}",
INITP_0D => X"{[17:9]_INITP_0D}",
INITP_0E => X"{[17:9]_INITP_0E}",
INITP_0F => X"{[17:9]_INITP_0F}")
port map( ADDRARDADDR => address_a,
ENARDEN => enable,
CLKARDCLK => clk,
DOADO => data_out_a_h(31 downto 0),
DOPADOP => data_out_a_h(35 downto 32),
DIADI => data_in_a(31 downto 0),
DIPADIP => data_in_a(35 downto 32),
WEA => "0000",
REGCEAREGCE => '0',
RSTRAMARSTRAM => '0',
RSTREGARSTREG => '0',
ADDRBWRADDR => address_b,
ENBWREN => enable_b,
CLKBWRCLK => clk_b,
DOBDO => data_out_b_h(31 downto 0),
DOPBDOP => data_out_b_h(35 downto 32),
DIBDI => data_in_b_h(31 downto 0),
DIPBDIP => data_in_b_h(35 downto 32),
WEBWE => we_b,
REGCEB => '0',
RSTRAMB => '0',
RSTREGB => '0',
CASCADEINA => '0',
CASCADEINB => '0',
INJECTDBITERR => '0',
INJECTSBITERR => '0');
--
end low_level_definition;
--
------------------------------------------------------------------------------------
--
-- END OF FILE {name}.vhd
--
------------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,284 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2011, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
ROM_form.vhd
Production template for a 1K program for KCPSM6 in a Spartan-6 device using a
RAMB18WER primitive.
Ken Chapman (Xilinx Ltd)
5th August 2011
This is a VHDL template file for the KCPSM6 assembler.
This VHDL file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.vhd' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the VHDL.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2011, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
--
-- Production definition of a 1K program for KCPSM6 in a Spartan-6 device using a
-- RAMB18WER primitive.
--
-- Note: The complete 12-bit address bus is connected to KCPSM6 to facilitate future code
-- expansion with minimum changes being required to the hardware description.
-- Only the lower 10-bits of the address are actually used for the 1K address range
-- 000 to 3FF hex.
--
-- Program defined by '{psmname}.psm'.
--
-- Generated by KCPSM6 Assembler: {timestamp}.
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
--
entity {name} is
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
clk : in std_logic);
end {name};
--
architecture low_level_definition of {name} is
--
signal address_a : std_logic_vector(13 downto 0);
signal data_in_a : std_logic_vector(35 downto 0);
signal data_out_a : std_logic_vector(35 downto 0);
signal address_b : std_logic_vector(13 downto 0);
signal data_in_b : std_logic_vector(35 downto 0);
signal data_out_b : std_logic_vector(35 downto 0);
signal enable_b : std_logic;
signal clk_b : std_logic;
signal we_b : std_logic_vector(3 downto 0);
--
begin
--
address_a <= address(9 downto 0) & "0000";
instruction <= data_out_a(33 downto 32) & data_out_a(15 downto 0);
data_in_a <= "0000000000000000000000000000000000" & address(11 downto 10);
--
address_b <= "00000000000000";
data_in_b <= "00" & data_out_b(33 downto 32) & "0000000000000000" & data_out_b(15 downto 0);
enable_b <= '0';
we_b <= "0000";
clk_b <= '0';
--
--
--
kcpsm6_rom: RAMB16BWER
generic map ( DATA_WIDTH_A => 18,
DOA_REG => 0,
EN_RSTRAM_A => FALSE,
INIT_A => X"000000000",
RST_PRIORITY_A => "CE",
SRVAL_A => X"000000000",
WRITE_MODE_A => "WRITE_FIRST",
DATA_WIDTH_B => 18,
DOB_REG => 0,
EN_RSTRAM_B => FALSE,
INIT_B => X"000000000",
RST_PRIORITY_B => "CE",
SRVAL_B => X"000000000",
WRITE_MODE_B => "WRITE_FIRST",
RSTTYPE => "SYNC",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
SIM_DEVICE => "SPARTAN6",
INIT_00 => X"{INIT_00}",
INIT_01 => X"{INIT_01}",
INIT_02 => X"{INIT_02}",
INIT_03 => X"{INIT_03}",
INIT_04 => X"{INIT_04}",
INIT_05 => X"{INIT_05}",
INIT_06 => X"{INIT_06}",
INIT_07 => X"{INIT_07}",
INIT_08 => X"{INIT_08}",
INIT_09 => X"{INIT_09}",
INIT_0A => X"{INIT_0A}",
INIT_0B => X"{INIT_0B}",
INIT_0C => X"{INIT_0C}",
INIT_0D => X"{INIT_0D}",
INIT_0E => X"{INIT_0E}",
INIT_0F => X"{INIT_0F}",
INIT_10 => X"{INIT_10}",
INIT_11 => X"{INIT_11}",
INIT_12 => X"{INIT_12}",
INIT_13 => X"{INIT_13}",
INIT_14 => X"{INIT_14}",
INIT_15 => X"{INIT_15}",
INIT_16 => X"{INIT_16}",
INIT_17 => X"{INIT_17}",
INIT_18 => X"{INIT_18}",
INIT_19 => X"{INIT_19}",
INIT_1A => X"{INIT_1A}",
INIT_1B => X"{INIT_1B}",
INIT_1C => X"{INIT_1C}",
INIT_1D => X"{INIT_1D}",
INIT_1E => X"{INIT_1E}",
INIT_1F => X"{INIT_1F}",
INIT_20 => X"{INIT_20}",
INIT_21 => X"{INIT_21}",
INIT_22 => X"{INIT_22}",
INIT_23 => X"{INIT_23}",
INIT_24 => X"{INIT_24}",
INIT_25 => X"{INIT_25}",
INIT_26 => X"{INIT_26}",
INIT_27 => X"{INIT_27}",
INIT_28 => X"{INIT_28}",
INIT_29 => X"{INIT_29}",
INIT_2A => X"{INIT_2A}",
INIT_2B => X"{INIT_2B}",
INIT_2C => X"{INIT_2C}",
INIT_2D => X"{INIT_2D}",
INIT_2E => X"{INIT_2E}",
INIT_2F => X"{INIT_2F}",
INIT_30 => X"{INIT_30}",
INIT_31 => X"{INIT_31}",
INIT_32 => X"{INIT_32}",
INIT_33 => X"{INIT_33}",
INIT_34 => X"{INIT_34}",
INIT_35 => X"{INIT_35}",
INIT_36 => X"{INIT_36}",
INIT_37 => X"{INIT_37}",
INIT_38 => X"{INIT_38}",
INIT_39 => X"{INIT_39}",
INIT_3A => X"{INIT_3A}",
INIT_3B => X"{INIT_3B}",
INIT_3C => X"{INIT_3C}",
INIT_3D => X"{INIT_3D}",
INIT_3E => X"{INIT_3E}",
INIT_3F => X"{INIT_3F}",
INITP_00 => X"{INITP_00}",
INITP_01 => X"{INITP_01}",
INITP_02 => X"{INITP_02}",
INITP_03 => X"{INITP_03}",
INITP_04 => X"{INITP_04}",
INITP_05 => X"{INITP_05}",
INITP_06 => X"{INITP_06}",
INITP_07 => X"{INITP_07}")
port map( ADDRA => address_a,
ENA => enable,
CLKA => clk,
DOA => data_out_a(31 downto 0),
DOPA => data_out_a(35 downto 32),
DIA => data_in_a(31 downto 0),
DIPA => data_in_a(35 downto 32),
WEA => "0000",
REGCEA => '0',
RSTA => '0',
ADDRB => address_b,
ENB => enable_b,
CLKB => clk_b,
DOB => data_out_b(31 downto 0),
DOPB => data_out_b(35 downto 32),
DIB => data_in_b(31 downto 0),
DIPB => data_in_b(35 downto 32),
WEB => we_b,
REGCEB => '0',
RSTB => '0');
--
--
end low_level_definition;
--
------------------------------------------------------------------------------------
--
-- END OF FILE {name}.vhd
--
------------------------------------------------------------------------------------

View File

@ -0,0 +1,402 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2011, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
ROM_form.vhd
Production template for a 2K program for KCPSM6 in a Spartan-6 device using
2 x RAMB18WER primitives.
Ken Chapman (Xilinx Ltd)
5th August 2011
This is a VHDL template file for the KCPSM6 assembler.
This VHDL file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.vhd' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the VHDL.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2011, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
--
-- Production definition of a 2K program for KCPSM6 in a Spartan-6 device using
-- 2 x RAMB18WER primitives.
--
-- Note: The complete 12-bit address bus is connected to KCPSM6 to facilitate future code
-- expansion with minimum changes being required to the hardware description.
-- Only the lower 11-bits of the address are actually used for the 2K address range
-- 000 to 7FF hex.
--
-- Program defined by '{psmname}.psm'.
--
-- Generated by KCPSM6 Assembler: {timestamp}.
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
--
entity {name} is
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
clk : in std_logic);
end {name};
--
architecture low_level_definition of {name} is
--
signal address_a : std_logic_vector(13 downto 0);
signal data_in_a : std_logic_vector(35 downto 0);
signal data_out_a_l : std_logic_vector(35 downto 0);
signal data_out_a_h : std_logic_vector(35 downto 0);
signal address_b : std_logic_vector(13 downto 0);
signal data_in_b_l : std_logic_vector(35 downto 0);
signal data_out_b_l : std_logic_vector(35 downto 0);
signal data_in_b_h : std_logic_vector(35 downto 0);
signal data_out_b_h : std_logic_vector(35 downto 0);
signal enable_b : std_logic;
signal clk_b : std_logic;
signal we_b : std_logic_vector(3 downto 0);
--
begin
--
address_a <= address(10 downto 0) & "000";
instruction <= data_out_a_h(32) & data_out_a_h(7 downto 0) & data_out_a_l(32) & data_out_a_l(7 downto 0);
data_in_a <= "00000000000000000000000000000000000" & address(11);
--
address_b <= "00000000000000";
data_in_b_l <= "000" & data_out_b_l(32) & "000000000000000000000000" & data_out_b_l(7 downto 0);
data_in_b_h <= "000" & data_out_b_h(32) & "000000000000000000000000" & data_out_b_h(7 downto 0);
enable_b <= '0';
we_b <= "0000";
clk_b <= '0';
--
--
--
kcpsm6_rom_l: RAMB16BWER
generic map ( DATA_WIDTH_A => 9,
DOA_REG => 0,
EN_RSTRAM_A => FALSE,
INIT_A => X"000000000",
RST_PRIORITY_A => "CE",
SRVAL_A => X"000000000",
WRITE_MODE_A => "WRITE_FIRST",
DATA_WIDTH_B => 9,
DOB_REG => 0,
EN_RSTRAM_B => FALSE,
INIT_B => X"000000000",
RST_PRIORITY_B => "CE",
SRVAL_B => X"000000000",
WRITE_MODE_B => "WRITE_FIRST",
RSTTYPE => "SYNC",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
SIM_DEVICE => "SPARTAN6",
INIT_00 => X"{[8:0]_INIT_00}",
INIT_01 => X"{[8:0]_INIT_01}",
INIT_02 => X"{[8:0]_INIT_02}",
INIT_03 => X"{[8:0]_INIT_03}",
INIT_04 => X"{[8:0]_INIT_04}",
INIT_05 => X"{[8:0]_INIT_05}",
INIT_06 => X"{[8:0]_INIT_06}",
INIT_07 => X"{[8:0]_INIT_07}",
INIT_08 => X"{[8:0]_INIT_08}",
INIT_09 => X"{[8:0]_INIT_09}",
INIT_0A => X"{[8:0]_INIT_0A}",
INIT_0B => X"{[8:0]_INIT_0B}",
INIT_0C => X"{[8:0]_INIT_0C}",
INIT_0D => X"{[8:0]_INIT_0D}",
INIT_0E => X"{[8:0]_INIT_0E}",
INIT_0F => X"{[8:0]_INIT_0F}",
INIT_10 => X"{[8:0]_INIT_10}",
INIT_11 => X"{[8:0]_INIT_11}",
INIT_12 => X"{[8:0]_INIT_12}",
INIT_13 => X"{[8:0]_INIT_13}",
INIT_14 => X"{[8:0]_INIT_14}",
INIT_15 => X"{[8:0]_INIT_15}",
INIT_16 => X"{[8:0]_INIT_16}",
INIT_17 => X"{[8:0]_INIT_17}",
INIT_18 => X"{[8:0]_INIT_18}",
INIT_19 => X"{[8:0]_INIT_19}",
INIT_1A => X"{[8:0]_INIT_1A}",
INIT_1B => X"{[8:0]_INIT_1B}",
INIT_1C => X"{[8:0]_INIT_1C}",
INIT_1D => X"{[8:0]_INIT_1D}",
INIT_1E => X"{[8:0]_INIT_1E}",
INIT_1F => X"{[8:0]_INIT_1F}",
INIT_20 => X"{[8:0]_INIT_20}",
INIT_21 => X"{[8:0]_INIT_21}",
INIT_22 => X"{[8:0]_INIT_22}",
INIT_23 => X"{[8:0]_INIT_23}",
INIT_24 => X"{[8:0]_INIT_24}",
INIT_25 => X"{[8:0]_INIT_25}",
INIT_26 => X"{[8:0]_INIT_26}",
INIT_27 => X"{[8:0]_INIT_27}",
INIT_28 => X"{[8:0]_INIT_28}",
INIT_29 => X"{[8:0]_INIT_29}",
INIT_2A => X"{[8:0]_INIT_2A}",
INIT_2B => X"{[8:0]_INIT_2B}",
INIT_2C => X"{[8:0]_INIT_2C}",
INIT_2D => X"{[8:0]_INIT_2D}",
INIT_2E => X"{[8:0]_INIT_2E}",
INIT_2F => X"{[8:0]_INIT_2F}",
INIT_30 => X"{[8:0]_INIT_30}",
INIT_31 => X"{[8:0]_INIT_31}",
INIT_32 => X"{[8:0]_INIT_32}",
INIT_33 => X"{[8:0]_INIT_33}",
INIT_34 => X"{[8:0]_INIT_34}",
INIT_35 => X"{[8:0]_INIT_35}",
INIT_36 => X"{[8:0]_INIT_36}",
INIT_37 => X"{[8:0]_INIT_37}",
INIT_38 => X"{[8:0]_INIT_38}",
INIT_39 => X"{[8:0]_INIT_39}",
INIT_3A => X"{[8:0]_INIT_3A}",
INIT_3B => X"{[8:0]_INIT_3B}",
INIT_3C => X"{[8:0]_INIT_3C}",
INIT_3D => X"{[8:0]_INIT_3D}",
INIT_3E => X"{[8:0]_INIT_3E}",
INIT_3F => X"{[8:0]_INIT_3F}",
INITP_00 => X"{[8:0]_INITP_00}",
INITP_01 => X"{[8:0]_INITP_01}",
INITP_02 => X"{[8:0]_INITP_02}",
INITP_03 => X"{[8:0]_INITP_03}",
INITP_04 => X"{[8:0]_INITP_04}",
INITP_05 => X"{[8:0]_INITP_05}",
INITP_06 => X"{[8:0]_INITP_06}",
INITP_07 => X"{[8:0]_INITP_07}")
port map( ADDRA => address_a,
ENA => enable,
CLKA => clk,
DOA => data_out_a_l(31 downto 0),
DOPA => data_out_a_l(35 downto 32),
DIA => data_in_a(31 downto 0),
DIPA => data_in_a(35 downto 32),
WEA => "0000",
REGCEA => '0',
RSTA => '0',
ADDRB => address_b,
ENB => enable_b,
CLKB => clk_b,
DOB => data_out_b_l(31 downto 0),
DOPB => data_out_b_l(35 downto 32),
DIB => data_in_b_l(31 downto 0),
DIPB => data_in_b_l(35 downto 32),
WEB => we_b,
REGCEB => '0',
RSTB => '0');
--
--
--
kcpsm6_rom_h: RAMB16BWER
generic map ( DATA_WIDTH_A => 9,
DOA_REG => 0,
EN_RSTRAM_A => FALSE,
INIT_A => X"000000000",
RST_PRIORITY_A => "CE",
SRVAL_A => X"000000000",
WRITE_MODE_A => "WRITE_FIRST",
DATA_WIDTH_B => 9,
DOB_REG => 0,
EN_RSTRAM_B => FALSE,
INIT_B => X"000000000",
RST_PRIORITY_B => "CE",
SRVAL_B => X"000000000",
WRITE_MODE_B => "WRITE_FIRST",
RSTTYPE => "SYNC",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
SIM_DEVICE => "SPARTAN6",
INIT_00 => X"{[17:9]_INIT_00}",
INIT_01 => X"{[17:9]_INIT_01}",
INIT_02 => X"{[17:9]_INIT_02}",
INIT_03 => X"{[17:9]_INIT_03}",
INIT_04 => X"{[17:9]_INIT_04}",
INIT_05 => X"{[17:9]_INIT_05}",
INIT_06 => X"{[17:9]_INIT_06}",
INIT_07 => X"{[17:9]_INIT_07}",
INIT_08 => X"{[17:9]_INIT_08}",
INIT_09 => X"{[17:9]_INIT_09}",
INIT_0A => X"{[17:9]_INIT_0A}",
INIT_0B => X"{[17:9]_INIT_0B}",
INIT_0C => X"{[17:9]_INIT_0C}",
INIT_0D => X"{[17:9]_INIT_0D}",
INIT_0E => X"{[17:9]_INIT_0E}",
INIT_0F => X"{[17:9]_INIT_0F}",
INIT_10 => X"{[17:9]_INIT_10}",
INIT_11 => X"{[17:9]_INIT_11}",
INIT_12 => X"{[17:9]_INIT_12}",
INIT_13 => X"{[17:9]_INIT_13}",
INIT_14 => X"{[17:9]_INIT_14}",
INIT_15 => X"{[17:9]_INIT_15}",
INIT_16 => X"{[17:9]_INIT_16}",
INIT_17 => X"{[17:9]_INIT_17}",
INIT_18 => X"{[17:9]_INIT_18}",
INIT_19 => X"{[17:9]_INIT_19}",
INIT_1A => X"{[17:9]_INIT_1A}",
INIT_1B => X"{[17:9]_INIT_1B}",
INIT_1C => X"{[17:9]_INIT_1C}",
INIT_1D => X"{[17:9]_INIT_1D}",
INIT_1E => X"{[17:9]_INIT_1E}",
INIT_1F => X"{[17:9]_INIT_1F}",
INIT_20 => X"{[17:9]_INIT_20}",
INIT_21 => X"{[17:9]_INIT_21}",
INIT_22 => X"{[17:9]_INIT_22}",
INIT_23 => X"{[17:9]_INIT_23}",
INIT_24 => X"{[17:9]_INIT_24}",
INIT_25 => X"{[17:9]_INIT_25}",
INIT_26 => X"{[17:9]_INIT_26}",
INIT_27 => X"{[17:9]_INIT_27}",
INIT_28 => X"{[17:9]_INIT_28}",
INIT_29 => X"{[17:9]_INIT_29}",
INIT_2A => X"{[17:9]_INIT_2A}",
INIT_2B => X"{[17:9]_INIT_2B}",
INIT_2C => X"{[17:9]_INIT_2C}",
INIT_2D => X"{[17:9]_INIT_2D}",
INIT_2E => X"{[17:9]_INIT_2E}",
INIT_2F => X"{[17:9]_INIT_2F}",
INIT_30 => X"{[17:9]_INIT_30}",
INIT_31 => X"{[17:9]_INIT_31}",
INIT_32 => X"{[17:9]_INIT_32}",
INIT_33 => X"{[17:9]_INIT_33}",
INIT_34 => X"{[17:9]_INIT_34}",
INIT_35 => X"{[17:9]_INIT_35}",
INIT_36 => X"{[17:9]_INIT_36}",
INIT_37 => X"{[17:9]_INIT_37}",
INIT_38 => X"{[17:9]_INIT_38}",
INIT_39 => X"{[17:9]_INIT_39}",
INIT_3A => X"{[17:9]_INIT_3A}",
INIT_3B => X"{[17:9]_INIT_3B}",
INIT_3C => X"{[17:9]_INIT_3C}",
INIT_3D => X"{[17:9]_INIT_3D}",
INIT_3E => X"{[17:9]_INIT_3E}",
INIT_3F => X"{[17:9]_INIT_3F}",
INITP_00 => X"{[17:9]_INITP_00}",
INITP_01 => X"{[17:9]_INITP_01}",
INITP_02 => X"{[17:9]_INITP_02}",
INITP_03 => X"{[17:9]_INITP_03}",
INITP_04 => X"{[17:9]_INITP_04}",
INITP_05 => X"{[17:9]_INITP_05}",
INITP_06 => X"{[17:9]_INITP_06}",
INITP_07 => X"{[17:9]_INITP_07}")
port map( ADDRA => address_a,
ENA => enable,
CLKA => clk,
DOA => data_out_a_h(31 downto 0),
DOPA => data_out_a_h(35 downto 32),
DIA => data_in_a(31 downto 0),
DIPA => data_in_a(35 downto 32),
WEA => "0000",
REGCEA => '0',
RSTA => '0',
ADDRB => address_b,
ENB => enable_b,
CLKB => clk_b,
DOB => data_out_b_h(31 downto 0),
DOPB => data_out_b_h(35 downto 32),
DIB => data_in_b_h(31 downto 0),
DIPB => data_in_b_h(35 downto 32),
WEB => we_b,
REGCEB => '0',
RSTB => '0');
--
--
end low_level_definition;
--
------------------------------------------------------------------------------------
--
-- END OF FILE {name}.vhd
--
------------------------------------------------------------------------------------

View File

@ -0,0 +1,742 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2012, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
ROM_form.vhd
Production template for a 4K KCPSM6 program in a Spartan-6 device using
4 x RAMB18WER. It should be noted that a 4K program is not such a natural fit in
a Spartan-6 device and the implementation also requires a small amount of logic
(9 x LUT6_2 and an FD) resulting in slightly lower performance compared with
memories for 1K and 2K programs.
Ken Chapman (Xilinx Ltd)
23rd November 2012
This is a VHDL template file for the KCPSM6 assembler.
This VHDL file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.vhd' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the VHDL.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2012, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
--
-- Production definition of a 4K program for KCPSM6 in a Spartan-6 device using
-- 4 x RAMB18WER. It should be noted that a 4K program is not such a natural fit in
-- a Spartan-6 device and the implementation also requires a small amount of logic
-- (9 x LUT6_2 and an FD) resulting in slightly lower performance compared with
-- memories for 1K and 2K programs.
--
--
-- Program defined by '{psmname}.psm'.
--
-- Generated by KCPSM6 Assembler: {timestamp}.
--
-- Assembler used ROM_form template: 23rd November 2012
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
--
entity {name} is
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
clk : in std_logic);
end {name};
--
architecture low_level_definition of {name} is
--
signal address_a : std_logic_vector(13 downto 0);
signal pipe_a11 : std_logic;
signal data_in_a : std_logic_vector(35 downto 0);
signal data_out_a_ll : std_logic_vector(35 downto 0);
signal data_out_a_lh : std_logic_vector(35 downto 0);
signal data_out_a_hl : std_logic_vector(35 downto 0);
signal data_out_a_hh : std_logic_vector(35 downto 0);
signal address_b : std_logic_vector(13 downto 0);
signal data_in_b_ll : std_logic_vector(35 downto 0);
signal data_out_b_ll : std_logic_vector(35 downto 0);
signal data_in_b_lh : std_logic_vector(35 downto 0);
signal data_out_b_lh : std_logic_vector(35 downto 0);
signal data_in_b_hl : std_logic_vector(35 downto 0);
signal data_out_b_hl : std_logic_vector(35 downto 0);
signal data_in_b_hh : std_logic_vector(35 downto 0);
signal data_out_b_hh : std_logic_vector(35 downto 0);
signal enable_b : std_logic;
signal clk_b : std_logic;
signal we_b : std_logic_vector(3 downto 0);
--
begin
--
address_a <= address(10 downto 0) & "000";
data_in_a <= "000000000000000000000000000000000000";
--
s6_a11_flop: FD
port map ( D => address(11),
Q => pipe_a11,
C => clk);
--
s6_4k_mux0_lut: LUT6_2
generic map (INIT => X"FF00F0F0CCCCAAAA")
port map( I0 => data_out_a_ll(0),
I1 => data_out_a_hl(0),
I2 => data_out_a_ll(1),
I3 => data_out_a_hl(1),
I4 => pipe_a11,
I5 => '1',
O5 => instruction(0),
O6 => instruction(1));
--
s6_4k_mux2_lut: LUT6_2
generic map (INIT => X"FF00F0F0CCCCAAAA")
port map( I0 => data_out_a_ll(2),
I1 => data_out_a_hl(2),
I2 => data_out_a_ll(3),
I3 => data_out_a_hl(3),
I4 => pipe_a11,
I5 => '1',
O5 => instruction(2),
O6 => instruction(3));
--
s6_4k_mux4_lut: LUT6_2
generic map (INIT => X"FF00F0F0CCCCAAAA")
port map( I0 => data_out_a_ll(4),
I1 => data_out_a_hl(4),
I2 => data_out_a_ll(5),
I3 => data_out_a_hl(5),
I4 => pipe_a11,
I5 => '1',
O5 => instruction(4),
O6 => instruction(5));
--
s6_4k_mux6_lut: LUT6_2
generic map (INIT => X"FF00F0F0CCCCAAAA")
port map( I0 => data_out_a_ll(6),
I1 => data_out_a_hl(6),
I2 => data_out_a_ll(7),
I3 => data_out_a_hl(7),
I4 => pipe_a11,
I5 => '1',
O5 => instruction(6),
O6 => instruction(7));
--
s6_4k_mux8_lut: LUT6_2
generic map (INIT => X"FF00F0F0CCCCAAAA")
port map( I0 => data_out_a_ll(32),
I1 => data_out_a_hl(32),
I2 => data_out_a_lh(0),
I3 => data_out_a_hh(0),
I4 => pipe_a11,
I5 => '1',
O5 => instruction(8),
O6 => instruction(9));
--
s6_4k_mux10_lut: LUT6_2
generic map (INIT => X"FF00F0F0CCCCAAAA")
port map( I0 => data_out_a_lh(1),
I1 => data_out_a_hh(1),
I2 => data_out_a_lh(2),
I3 => data_out_a_hh(2),
I4 => pipe_a11,
I5 => '1',
O5 => instruction(10),
O6 => instruction(11));
--
s6_4k_mux12_lut: LUT6_2
generic map (INIT => X"FF00F0F0CCCCAAAA")
port map( I0 => data_out_a_lh(3),
I1 => data_out_a_hh(3),
I2 => data_out_a_lh(4),
I3 => data_out_a_hh(4),
I4 => pipe_a11,
I5 => '1',
O5 => instruction(12),
O6 => instruction(13));
--
s6_4k_mux14_lut: LUT6_2
generic map (INIT => X"FF00F0F0CCCCAAAA")
port map( I0 => data_out_a_lh(5),
I1 => data_out_a_hh(5),
I2 => data_out_a_lh(6),
I3 => data_out_a_hh(6),
I4 => pipe_a11,
I5 => '1',
O5 => instruction(14),
O6 => instruction(15));
--
s6_4k_mux16_lut: LUT6_2
generic map (INIT => X"FF00F0F0CCCCAAAA")
port map( I0 => data_out_a_lh(7),
I1 => data_out_a_hh(7),
I2 => data_out_a_lh(32),
I3 => data_out_a_hh(32),
I4 => pipe_a11,
I5 => '1',
O5 => instruction(16),
O6 => instruction(17));
--
address_b <= "00000000000000";
data_in_b_ll <= "000" & data_out_b_ll(32) & "000000000000000000000000" & data_out_b_ll(7 downto 0);
data_in_b_lh <= "000" & data_out_b_lh(32) & "000000000000000000000000" & data_out_b_lh(7 downto 0);
data_in_b_hl <= "000" & data_out_b_hl(32) & "000000000000000000000000" & data_out_b_hl(7 downto 0);
data_in_b_hh <= "000" & data_out_b_hh(32) & "000000000000000000000000" & data_out_b_hh(7 downto 0);
enable_b <= '0';
we_b <= "0000";
clk_b <= '0';
--
--
--
kcpsm6_rom_ll: RAMB16BWER
generic map ( DATA_WIDTH_A => 9,
DOA_REG => 0,
EN_RSTRAM_A => FALSE,
INIT_A => X"000000000",
RST_PRIORITY_A => "CE",
SRVAL_A => X"000000000",
WRITE_MODE_A => "WRITE_FIRST",
DATA_WIDTH_B => 9,
DOB_REG => 0,
EN_RSTRAM_B => FALSE,
INIT_B => X"000000000",
RST_PRIORITY_B => "CE",
SRVAL_B => X"000000000",
WRITE_MODE_B => "WRITE_FIRST",
RSTTYPE => "SYNC",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
SIM_DEVICE => "SPARTAN6",
INIT_00 => X"{[8:0]_INIT_00}",
INIT_01 => X"{[8:0]_INIT_01}",
INIT_02 => X"{[8:0]_INIT_02}",
INIT_03 => X"{[8:0]_INIT_03}",
INIT_04 => X"{[8:0]_INIT_04}",
INIT_05 => X"{[8:0]_INIT_05}",
INIT_06 => X"{[8:0]_INIT_06}",
INIT_07 => X"{[8:0]_INIT_07}",
INIT_08 => X"{[8:0]_INIT_08}",
INIT_09 => X"{[8:0]_INIT_09}",
INIT_0A => X"{[8:0]_INIT_0A}",
INIT_0B => X"{[8:0]_INIT_0B}",
INIT_0C => X"{[8:0]_INIT_0C}",
INIT_0D => X"{[8:0]_INIT_0D}",
INIT_0E => X"{[8:0]_INIT_0E}",
INIT_0F => X"{[8:0]_INIT_0F}",
INIT_10 => X"{[8:0]_INIT_10}",
INIT_11 => X"{[8:0]_INIT_11}",
INIT_12 => X"{[8:0]_INIT_12}",
INIT_13 => X"{[8:0]_INIT_13}",
INIT_14 => X"{[8:0]_INIT_14}",
INIT_15 => X"{[8:0]_INIT_15}",
INIT_16 => X"{[8:0]_INIT_16}",
INIT_17 => X"{[8:0]_INIT_17}",
INIT_18 => X"{[8:0]_INIT_18}",
INIT_19 => X"{[8:0]_INIT_19}",
INIT_1A => X"{[8:0]_INIT_1A}",
INIT_1B => X"{[8:0]_INIT_1B}",
INIT_1C => X"{[8:0]_INIT_1C}",
INIT_1D => X"{[8:0]_INIT_1D}",
INIT_1E => X"{[8:0]_INIT_1E}",
INIT_1F => X"{[8:0]_INIT_1F}",
INIT_20 => X"{[8:0]_INIT_20}",
INIT_21 => X"{[8:0]_INIT_21}",
INIT_22 => X"{[8:0]_INIT_22}",
INIT_23 => X"{[8:0]_INIT_23}",
INIT_24 => X"{[8:0]_INIT_24}",
INIT_25 => X"{[8:0]_INIT_25}",
INIT_26 => X"{[8:0]_INIT_26}",
INIT_27 => X"{[8:0]_INIT_27}",
INIT_28 => X"{[8:0]_INIT_28}",
INIT_29 => X"{[8:0]_INIT_29}",
INIT_2A => X"{[8:0]_INIT_2A}",
INIT_2B => X"{[8:0]_INIT_2B}",
INIT_2C => X"{[8:0]_INIT_2C}",
INIT_2D => X"{[8:0]_INIT_2D}",
INIT_2E => X"{[8:0]_INIT_2E}",
INIT_2F => X"{[8:0]_INIT_2F}",
INIT_30 => X"{[8:0]_INIT_30}",
INIT_31 => X"{[8:0]_INIT_31}",
INIT_32 => X"{[8:0]_INIT_32}",
INIT_33 => X"{[8:0]_INIT_33}",
INIT_34 => X"{[8:0]_INIT_34}",
INIT_35 => X"{[8:0]_INIT_35}",
INIT_36 => X"{[8:0]_INIT_36}",
INIT_37 => X"{[8:0]_INIT_37}",
INIT_38 => X"{[8:0]_INIT_38}",
INIT_39 => X"{[8:0]_INIT_39}",
INIT_3A => X"{[8:0]_INIT_3A}",
INIT_3B => X"{[8:0]_INIT_3B}",
INIT_3C => X"{[8:0]_INIT_3C}",
INIT_3D => X"{[8:0]_INIT_3D}",
INIT_3E => X"{[8:0]_INIT_3E}",
INIT_3F => X"{[8:0]_INIT_3F}",
INITP_00 => X"{[8:0]_INITP_00}",
INITP_01 => X"{[8:0]_INITP_01}",
INITP_02 => X"{[8:0]_INITP_02}",
INITP_03 => X"{[8:0]_INITP_03}",
INITP_04 => X"{[8:0]_INITP_04}",
INITP_05 => X"{[8:0]_INITP_05}",
INITP_06 => X"{[8:0]_INITP_06}",
INITP_07 => X"{[8:0]_INITP_07}")
port map( ADDRA => address_a,
ENA => enable,
CLKA => clk,
DOA => data_out_a_ll(31 downto 0),
DOPA => data_out_a_ll(35 downto 32),
DIA => data_in_a(31 downto 0),
DIPA => data_in_a(35 downto 32),
WEA => "0000",
REGCEA => '0',
RSTA => '0',
ADDRB => address_b,
ENB => enable_b,
CLKB => clk_b,
DOB => data_out_b_ll(31 downto 0),
DOPB => data_out_b_ll(35 downto 32),
DIB => data_in_b_ll(31 downto 0),
DIPB => data_in_b_ll(35 downto 32),
WEB => we_b,
REGCEB => '0',
RSTB => '0');
--
--
--
kcpsm6_rom_lh: RAMB16BWER
generic map ( DATA_WIDTH_A => 9,
DOA_REG => 0,
EN_RSTRAM_A => FALSE,
INIT_A => X"000000000",
RST_PRIORITY_A => "CE",
SRVAL_A => X"000000000",
WRITE_MODE_A => "WRITE_FIRST",
DATA_WIDTH_B => 9,
DOB_REG => 0,
EN_RSTRAM_B => FALSE,
INIT_B => X"000000000",
RST_PRIORITY_B => "CE",
SRVAL_B => X"000000000",
WRITE_MODE_B => "WRITE_FIRST",
RSTTYPE => "SYNC",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
SIM_DEVICE => "SPARTAN6",
INIT_00 => X"{[17:9]_INIT_00}",
INIT_01 => X"{[17:9]_INIT_01}",
INIT_02 => X"{[17:9]_INIT_02}",
INIT_03 => X"{[17:9]_INIT_03}",
INIT_04 => X"{[17:9]_INIT_04}",
INIT_05 => X"{[17:9]_INIT_05}",
INIT_06 => X"{[17:9]_INIT_06}",
INIT_07 => X"{[17:9]_INIT_07}",
INIT_08 => X"{[17:9]_INIT_08}",
INIT_09 => X"{[17:9]_INIT_09}",
INIT_0A => X"{[17:9]_INIT_0A}",
INIT_0B => X"{[17:9]_INIT_0B}",
INIT_0C => X"{[17:9]_INIT_0C}",
INIT_0D => X"{[17:9]_INIT_0D}",
INIT_0E => X"{[17:9]_INIT_0E}",
INIT_0F => X"{[17:9]_INIT_0F}",
INIT_10 => X"{[17:9]_INIT_10}",
INIT_11 => X"{[17:9]_INIT_11}",
INIT_12 => X"{[17:9]_INIT_12}",
INIT_13 => X"{[17:9]_INIT_13}",
INIT_14 => X"{[17:9]_INIT_14}",
INIT_15 => X"{[17:9]_INIT_15}",
INIT_16 => X"{[17:9]_INIT_16}",
INIT_17 => X"{[17:9]_INIT_17}",
INIT_18 => X"{[17:9]_INIT_18}",
INIT_19 => X"{[17:9]_INIT_19}",
INIT_1A => X"{[17:9]_INIT_1A}",
INIT_1B => X"{[17:9]_INIT_1B}",
INIT_1C => X"{[17:9]_INIT_1C}",
INIT_1D => X"{[17:9]_INIT_1D}",
INIT_1E => X"{[17:9]_INIT_1E}",
INIT_1F => X"{[17:9]_INIT_1F}",
INIT_20 => X"{[17:9]_INIT_20}",
INIT_21 => X"{[17:9]_INIT_21}",
INIT_22 => X"{[17:9]_INIT_22}",
INIT_23 => X"{[17:9]_INIT_23}",
INIT_24 => X"{[17:9]_INIT_24}",
INIT_25 => X"{[17:9]_INIT_25}",
INIT_26 => X"{[17:9]_INIT_26}",
INIT_27 => X"{[17:9]_INIT_27}",
INIT_28 => X"{[17:9]_INIT_28}",
INIT_29 => X"{[17:9]_INIT_29}",
INIT_2A => X"{[17:9]_INIT_2A}",
INIT_2B => X"{[17:9]_INIT_2B}",
INIT_2C => X"{[17:9]_INIT_2C}",
INIT_2D => X"{[17:9]_INIT_2D}",
INIT_2E => X"{[17:9]_INIT_2E}",
INIT_2F => X"{[17:9]_INIT_2F}",
INIT_30 => X"{[17:9]_INIT_30}",
INIT_31 => X"{[17:9]_INIT_31}",
INIT_32 => X"{[17:9]_INIT_32}",
INIT_33 => X"{[17:9]_INIT_33}",
INIT_34 => X"{[17:9]_INIT_34}",
INIT_35 => X"{[17:9]_INIT_35}",
INIT_36 => X"{[17:9]_INIT_36}",
INIT_37 => X"{[17:9]_INIT_37}",
INIT_38 => X"{[17:9]_INIT_38}",
INIT_39 => X"{[17:9]_INIT_39}",
INIT_3A => X"{[17:9]_INIT_3A}",
INIT_3B => X"{[17:9]_INIT_3B}",
INIT_3C => X"{[17:9]_INIT_3C}",
INIT_3D => X"{[17:9]_INIT_3D}",
INIT_3E => X"{[17:9]_INIT_3E}",
INIT_3F => X"{[17:9]_INIT_3F}",
INITP_00 => X"{[17:9]_INITP_00}",
INITP_01 => X"{[17:9]_INITP_01}",
INITP_02 => X"{[17:9]_INITP_02}",
INITP_03 => X"{[17:9]_INITP_03}",
INITP_04 => X"{[17:9]_INITP_04}",
INITP_05 => X"{[17:9]_INITP_05}",
INITP_06 => X"{[17:9]_INITP_06}",
INITP_07 => X"{[17:9]_INITP_07}")
port map( ADDRA => address_a,
ENA => enable,
CLKA => clk,
DOA => data_out_a_lh(31 downto 0),
DOPA => data_out_a_lh(35 downto 32),
DIA => data_in_a(31 downto 0),
DIPA => data_in_a(35 downto 32),
WEA => "0000",
REGCEA => '0',
RSTA => '0',
ADDRB => address_b,
ENB => enable_b,
CLKB => clk_b,
DOB => data_out_b_lh(31 downto 0),
DOPB => data_out_b_lh(35 downto 32),
DIB => data_in_b_lh(31 downto 0),
DIPB => data_in_b_lh(35 downto 32),
WEB => we_b,
REGCEB => '0',
RSTB => '0');
--
kcpsm6_rom_hl: RAMB16BWER
generic map ( DATA_WIDTH_A => 9,
DOA_REG => 0,
EN_RSTRAM_A => FALSE,
INIT_A => X"000000000",
RST_PRIORITY_A => "CE",
SRVAL_A => X"000000000",
WRITE_MODE_A => "WRITE_FIRST",
DATA_WIDTH_B => 9,
DOB_REG => 0,
EN_RSTRAM_B => FALSE,
INIT_B => X"000000000",
RST_PRIORITY_B => "CE",
SRVAL_B => X"000000000",
WRITE_MODE_B => "WRITE_FIRST",
RSTTYPE => "SYNC",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
SIM_DEVICE => "SPARTAN6",
INIT_00 => X"{[8:0]_INIT_40}",
INIT_01 => X"{[8:0]_INIT_41}",
INIT_02 => X"{[8:0]_INIT_42}",
INIT_03 => X"{[8:0]_INIT_43}",
INIT_04 => X"{[8:0]_INIT_44}",
INIT_05 => X"{[8:0]_INIT_45}",
INIT_06 => X"{[8:0]_INIT_46}",
INIT_07 => X"{[8:0]_INIT_47}",
INIT_08 => X"{[8:0]_INIT_48}",
INIT_09 => X"{[8:0]_INIT_49}",
INIT_0A => X"{[8:0]_INIT_4A}",
INIT_0B => X"{[8:0]_INIT_4B}",
INIT_0C => X"{[8:0]_INIT_4C}",
INIT_0D => X"{[8:0]_INIT_4D}",
INIT_0E => X"{[8:0]_INIT_4E}",
INIT_0F => X"{[8:0]_INIT_4F}",
INIT_10 => X"{[8:0]_INIT_50}",
INIT_11 => X"{[8:0]_INIT_51}",
INIT_12 => X"{[8:0]_INIT_52}",
INIT_13 => X"{[8:0]_INIT_53}",
INIT_14 => X"{[8:0]_INIT_54}",
INIT_15 => X"{[8:0]_INIT_55}",
INIT_16 => X"{[8:0]_INIT_56}",
INIT_17 => X"{[8:0]_INIT_57}",
INIT_18 => X"{[8:0]_INIT_58}",
INIT_19 => X"{[8:0]_INIT_59}",
INIT_1A => X"{[8:0]_INIT_5A}",
INIT_1B => X"{[8:0]_INIT_5B}",
INIT_1C => X"{[8:0]_INIT_5C}",
INIT_1D => X"{[8:0]_INIT_5D}",
INIT_1E => X"{[8:0]_INIT_5E}",
INIT_1F => X"{[8:0]_INIT_5F}",
INIT_20 => X"{[8:0]_INIT_60}",
INIT_21 => X"{[8:0]_INIT_61}",
INIT_22 => X"{[8:0]_INIT_62}",
INIT_23 => X"{[8:0]_INIT_63}",
INIT_24 => X"{[8:0]_INIT_64}",
INIT_25 => X"{[8:0]_INIT_65}",
INIT_26 => X"{[8:0]_INIT_66}",
INIT_27 => X"{[8:0]_INIT_67}",
INIT_28 => X"{[8:0]_INIT_68}",
INIT_29 => X"{[8:0]_INIT_69}",
INIT_2A => X"{[8:0]_INIT_6A}",
INIT_2B => X"{[8:0]_INIT_6B}",
INIT_2C => X"{[8:0]_INIT_6C}",
INIT_2D => X"{[8:0]_INIT_6D}",
INIT_2E => X"{[8:0]_INIT_6E}",
INIT_2F => X"{[8:0]_INIT_6F}",
INIT_30 => X"{[8:0]_INIT_70}",
INIT_31 => X"{[8:0]_INIT_71}",
INIT_32 => X"{[8:0]_INIT_72}",
INIT_33 => X"{[8:0]_INIT_73}",
INIT_34 => X"{[8:0]_INIT_74}",
INIT_35 => X"{[8:0]_INIT_75}",
INIT_36 => X"{[8:0]_INIT_76}",
INIT_37 => X"{[8:0]_INIT_77}",
INIT_38 => X"{[8:0]_INIT_78}",
INIT_39 => X"{[8:0]_INIT_79}",
INIT_3A => X"{[8:0]_INIT_7A}",
INIT_3B => X"{[8:0]_INIT_7B}",
INIT_3C => X"{[8:0]_INIT_7C}",
INIT_3D => X"{[8:0]_INIT_7D}",
INIT_3E => X"{[8:0]_INIT_7E}",
INIT_3F => X"{[8:0]_INIT_7F}",
INITP_00 => X"{[8:0]_INITP_08}",
INITP_01 => X"{[8:0]_INITP_09}",
INITP_02 => X"{[8:0]_INITP_0A}",
INITP_03 => X"{[8:0]_INITP_0B}",
INITP_04 => X"{[8:0]_INITP_0C}",
INITP_05 => X"{[8:0]_INITP_0D}",
INITP_06 => X"{[8:0]_INITP_0E}",
INITP_07 => X"{[8:0]_INITP_0F}")
port map( ADDRA => address_a,
ENA => enable,
CLKA => clk,
DOA => data_out_a_hl(31 downto 0),
DOPA => data_out_a_hl(35 downto 32),
DIA => data_in_a(31 downto 0),
DIPA => data_in_a(35 downto 32),
WEA => "0000",
REGCEA => '0',
RSTA => '0',
ADDRB => address_b,
ENB => enable_b,
CLKB => clk_b,
DOB => data_out_b_hl(31 downto 0),
DOPB => data_out_b_hl(35 downto 32),
DIB => data_in_b_hl(31 downto 0),
DIPB => data_in_b_hl(35 downto 32),
WEB => we_b,
REGCEB => '0',
RSTB => '0');
--
kcpsm6_rom_hh: RAMB16BWER
generic map ( DATA_WIDTH_A => 9,
DOA_REG => 0,
EN_RSTRAM_A => FALSE,
INIT_A => X"000000000",
RST_PRIORITY_A => "CE",
SRVAL_A => X"000000000",
WRITE_MODE_A => "WRITE_FIRST",
DATA_WIDTH_B => 9,
DOB_REG => 0,
EN_RSTRAM_B => FALSE,
INIT_B => X"000000000",
RST_PRIORITY_B => "CE",
SRVAL_B => X"000000000",
WRITE_MODE_B => "WRITE_FIRST",
RSTTYPE => "SYNC",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
SIM_DEVICE => "SPARTAN6",
INIT_00 => X"{[17:9]_INIT_40}",
INIT_01 => X"{[17:9]_INIT_41}",
INIT_02 => X"{[17:9]_INIT_42}",
INIT_03 => X"{[17:9]_INIT_43}",
INIT_04 => X"{[17:9]_INIT_44}",
INIT_05 => X"{[17:9]_INIT_45}",
INIT_06 => X"{[17:9]_INIT_46}",
INIT_07 => X"{[17:9]_INIT_47}",
INIT_08 => X"{[17:9]_INIT_48}",
INIT_09 => X"{[17:9]_INIT_49}",
INIT_0A => X"{[17:9]_INIT_4A}",
INIT_0B => X"{[17:9]_INIT_4B}",
INIT_0C => X"{[17:9]_INIT_4C}",
INIT_0D => X"{[17:9]_INIT_4D}",
INIT_0E => X"{[17:9]_INIT_4E}",
INIT_0F => X"{[17:9]_INIT_4F}",
INIT_10 => X"{[17:9]_INIT_50}",
INIT_11 => X"{[17:9]_INIT_51}",
INIT_12 => X"{[17:9]_INIT_52}",
INIT_13 => X"{[17:9]_INIT_53}",
INIT_14 => X"{[17:9]_INIT_54}",
INIT_15 => X"{[17:9]_INIT_55}",
INIT_16 => X"{[17:9]_INIT_56}",
INIT_17 => X"{[17:9]_INIT_57}",
INIT_18 => X"{[17:9]_INIT_58}",
INIT_19 => X"{[17:9]_INIT_59}",
INIT_1A => X"{[17:9]_INIT_5A}",
INIT_1B => X"{[17:9]_INIT_5B}",
INIT_1C => X"{[17:9]_INIT_5C}",
INIT_1D => X"{[17:9]_INIT_5D}",
INIT_1E => X"{[17:9]_INIT_5E}",
INIT_1F => X"{[17:9]_INIT_5F}",
INIT_20 => X"{[17:9]_INIT_60}",
INIT_21 => X"{[17:9]_INIT_61}",
INIT_22 => X"{[17:9]_INIT_62}",
INIT_23 => X"{[17:9]_INIT_63}",
INIT_24 => X"{[17:9]_INIT_64}",
INIT_25 => X"{[17:9]_INIT_65}",
INIT_26 => X"{[17:9]_INIT_66}",
INIT_27 => X"{[17:9]_INIT_67}",
INIT_28 => X"{[17:9]_INIT_68}",
INIT_29 => X"{[17:9]_INIT_69}",
INIT_2A => X"{[17:9]_INIT_6A}",
INIT_2B => X"{[17:9]_INIT_6B}",
INIT_2C => X"{[17:9]_INIT_6C}",
INIT_2D => X"{[17:9]_INIT_6D}",
INIT_2E => X"{[17:9]_INIT_6E}",
INIT_2F => X"{[17:9]_INIT_6F}",
INIT_30 => X"{[17:9]_INIT_70}",
INIT_31 => X"{[17:9]_INIT_71}",
INIT_32 => X"{[17:9]_INIT_72}",
INIT_33 => X"{[17:9]_INIT_73}",
INIT_34 => X"{[17:9]_INIT_74}",
INIT_35 => X"{[17:9]_INIT_75}",
INIT_36 => X"{[17:9]_INIT_76}",
INIT_37 => X"{[17:9]_INIT_77}",
INIT_38 => X"{[17:9]_INIT_78}",
INIT_39 => X"{[17:9]_INIT_79}",
INIT_3A => X"{[17:9]_INIT_7A}",
INIT_3B => X"{[17:9]_INIT_7B}",
INIT_3C => X"{[17:9]_INIT_7C}",
INIT_3D => X"{[17:9]_INIT_7D}",
INIT_3E => X"{[17:9]_INIT_7E}",
INIT_3F => X"{[17:9]_INIT_7F}",
INITP_00 => X"{[17:9]_INITP_08}",
INITP_01 => X"{[17:9]_INITP_09}",
INITP_02 => X"{[17:9]_INITP_0A}",
INITP_03 => X"{[17:9]_INITP_0B}",
INITP_04 => X"{[17:9]_INITP_0C}",
INITP_05 => X"{[17:9]_INITP_0D}",
INITP_06 => X"{[17:9]_INITP_0E}",
INITP_07 => X"{[17:9]_INITP_0F}")
port map( ADDRA => address_a,
ENA => enable,
CLKA => clk,
DOA => data_out_a_hh(31 downto 0),
DOPA => data_out_a_hh(35 downto 32),
DIA => data_in_a(31 downto 0),
DIPA => data_in_a(35 downto 32),
WEA => "0000",
REGCEA => '0',
RSTA => '0',
ADDRB => address_b,
ENB => enable_b,
CLKB => clk_b,
DOB => data_out_b_hh(31 downto 0),
DOPB => data_out_b_hh(35 downto 32),
DIB => data_in_b_hh(31 downto 0),
DIPB => data_in_b_hh(35 downto 32),
WEB => we_b,
REGCEB => '0',
RSTB => '0');
--
--
end low_level_definition;
--
------------------------------------------------------------------------------------
--
-- END OF FILE {name}.vhd
--
------------------------------------------------------------------------------------

View File

@ -0,0 +1,292 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
ROM_form.vhd
Production template for a 1K program for KCPSM6 in a Virtex-6 device using a
RAMB18E1 primitive.
Ken Chapman (Xilinx Ltd)
5th August 2011 - First Release
14th March 2013 - Unused address inputs on BRAMs connected High to reflect
descriptions UG363.
This is a VHDL template file for the KCPSM6 assembler.
This VHDL file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.vhd' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the VHDL.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
--
-- Production definition of a 1K program for KCPSM6 in a Virtex-6 device using a
-- RAMB18E1 primitive.
--
-- Note: The complete 12-bit address bus is connected to KCPSM6 to facilitate future code
-- expansion with minimum changes being required to the hardware description.
-- Only the lower 10-bits of the address are actually used for the 1K address range
-- 000 to 3FF hex.
--
-- Program defined by '{psmname}.psm'.
--
-- Generated by KCPSM6 Assembler: {timestamp}.
--
-- Assembler used ROM_form template: ROM_form_V6_1K_14March13.vhd
--
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
--
entity {name} is
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
clk : in std_logic);
end {name};
--
architecture low_level_definition of {name} is
--
signal address_a : std_logic_vector(13 downto 0);
signal data_in_a : std_logic_vector(17 downto 0);
signal data_out_a : std_logic_vector(17 downto 0);
signal address_b : std_logic_vector(13 downto 0);
signal data_in_b : std_logic_vector(17 downto 0);
signal data_out_b : std_logic_vector(17 downto 0);
signal enable_b : std_logic;
signal clk_b : std_logic;
signal we_b : std_logic_vector(3 downto 0);
--
begin
--
address_a <= address(9 downto 0) & "1111";
instruction <= data_out_a(17 downto 0);
data_in_a <= "0000000000000000" & address(11 downto 10);
--
address_b <= "11111111111111";
data_in_b <= data_out_b(17 downto 0);
enable_b <= '0';
we_b <= "0000";
clk_b <= '0';
--
--
--
kcpsm6_rom: RAMB18E1
generic map ( READ_WIDTH_A => 18,
WRITE_WIDTH_A => 18,
DOA_REG => 0,
INIT_A => "000000000000000000",
RSTREG_PRIORITY_A => "REGCE",
SRVAL_A => X"000000000000000000",
WRITE_MODE_A => "WRITE_FIRST",
READ_WIDTH_B => 18,
WRITE_WIDTH_B => 18,
DOB_REG => 0,
INIT_B => X"000000000000000000",
RSTREG_PRIORITY_B => "REGCE",
SRVAL_B => X"000000000000000000",
WRITE_MODE_B => "WRITE_FIRST",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
RAM_MODE => "TDP",
RDADDR_COLLISION_HWCONFIG => "DELAYED_WRITE",
SIM_DEVICE => "VIRTEX6",
INIT_00 => X"{INIT_00}",
INIT_01 => X"{INIT_01}",
INIT_02 => X"{INIT_02}",
INIT_03 => X"{INIT_03}",
INIT_04 => X"{INIT_04}",
INIT_05 => X"{INIT_05}",
INIT_06 => X"{INIT_06}",
INIT_07 => X"{INIT_07}",
INIT_08 => X"{INIT_08}",
INIT_09 => X"{INIT_09}",
INIT_0A => X"{INIT_0A}",
INIT_0B => X"{INIT_0B}",
INIT_0C => X"{INIT_0C}",
INIT_0D => X"{INIT_0D}",
INIT_0E => X"{INIT_0E}",
INIT_0F => X"{INIT_0F}",
INIT_10 => X"{INIT_10}",
INIT_11 => X"{INIT_11}",
INIT_12 => X"{INIT_12}",
INIT_13 => X"{INIT_13}",
INIT_14 => X"{INIT_14}",
INIT_15 => X"{INIT_15}",
INIT_16 => X"{INIT_16}",
INIT_17 => X"{INIT_17}",
INIT_18 => X"{INIT_18}",
INIT_19 => X"{INIT_19}",
INIT_1A => X"{INIT_1A}",
INIT_1B => X"{INIT_1B}",
INIT_1C => X"{INIT_1C}",
INIT_1D => X"{INIT_1D}",
INIT_1E => X"{INIT_1E}",
INIT_1F => X"{INIT_1F}",
INIT_20 => X"{INIT_20}",
INIT_21 => X"{INIT_21}",
INIT_22 => X"{INIT_22}",
INIT_23 => X"{INIT_23}",
INIT_24 => X"{INIT_24}",
INIT_25 => X"{INIT_25}",
INIT_26 => X"{INIT_26}",
INIT_27 => X"{INIT_27}",
INIT_28 => X"{INIT_28}",
INIT_29 => X"{INIT_29}",
INIT_2A => X"{INIT_2A}",
INIT_2B => X"{INIT_2B}",
INIT_2C => X"{INIT_2C}",
INIT_2D => X"{INIT_2D}",
INIT_2E => X"{INIT_2E}",
INIT_2F => X"{INIT_2F}",
INIT_30 => X"{INIT_30}",
INIT_31 => X"{INIT_31}",
INIT_32 => X"{INIT_32}",
INIT_33 => X"{INIT_33}",
INIT_34 => X"{INIT_34}",
INIT_35 => X"{INIT_35}",
INIT_36 => X"{INIT_36}",
INIT_37 => X"{INIT_37}",
INIT_38 => X"{INIT_38}",
INIT_39 => X"{INIT_39}",
INIT_3A => X"{INIT_3A}",
INIT_3B => X"{INIT_3B}",
INIT_3C => X"{INIT_3C}",
INIT_3D => X"{INIT_3D}",
INIT_3E => X"{INIT_3E}",
INIT_3F => X"{INIT_3F}",
INITP_00 => X"{INITP_00}",
INITP_01 => X"{INITP_01}",
INITP_02 => X"{INITP_02}",
INITP_03 => X"{INITP_03}",
INITP_04 => X"{INITP_04}",
INITP_05 => X"{INITP_05}",
INITP_06 => X"{INITP_06}",
INITP_07 => X"{INITP_07}")
port map( ADDRARDADDR => address_a,
ENARDEN => enable,
CLKARDCLK => clk,
DOADO => data_out_a(15 downto 0),
DOPADOP => data_out_a(17 downto 16),
DIADI => data_in_a(15 downto 0),
DIPADIP => data_in_a(17 downto 16),
WEA => "00",
REGCEAREGCE => '0',
RSTRAMARSTRAM => '0',
RSTREGARSTREG => '0',
ADDRBWRADDR => address_b,
ENBWREN => enable_b,
CLKBWRCLK => clk_b,
DOBDO => data_out_b(15 downto 0),
DOPBDOP => data_out_b(17 downto 16),
DIBDI => data_in_b(15 downto 0),
DIPBDIP => data_in_b(17 downto 16),
WEBWE => we_b,
REGCEB => '0',
RSTRAMB => '0',
RSTREGB => '0');
--
--
end low_level_definition;
--
------------------------------------------------------------------------------------
--
-- END OF FILE {name}.vhd
--
------------------------------------------------------------------------------------

View File

@ -0,0 +1,370 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
ROM_form.vhd
Production template for a 2K program for KCPSM6 in a Virtex-6 device using a
RAMB36E1 primitive.
Ken Chapman (Xilinx Ltd)
5th August 2011 - First Release
14th March 2013 - Unused address inputs on BRAMs connected High to reflect
descriptions UG363.
This is a VHDL template file for the KCPSM6 assembler.
This VHDL file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.vhd' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the VHDL.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
--
-- Production definition of a 2K program for KCPSM6 in a Virtex-6 device using a
-- RAMB36E1 primitive.
--
-- Note: The complete 12-bit address bus is connected to KCPSM6 to facilitate future code
-- expansion with minimum changes being required to the hardware description.
-- Only the lower 11-bits of the address are actually used for the 2K address range
-- 000 to 7FF hex.
--
-- Program defined by '{psmname}.psm'.
--
-- Generated by KCPSM6 Assembler: {timestamp}.
--
-- Assembler used ROM_form template: ROM_form_V6_2K_14March13.vhd
--
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
--
entity {name} is
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
clk : in std_logic);
end {name};
--
architecture low_level_definition of {name} is
--
signal address_a : std_logic_vector(15 downto 0);
signal data_in_a : std_logic_vector(35 downto 0);
signal data_out_a : std_logic_vector(35 downto 0);
signal address_b : std_logic_vector(15 downto 0);
signal data_in_b : std_logic_vector(35 downto 0);
signal data_out_b : std_logic_vector(35 downto 0);
signal enable_b : std_logic;
signal clk_b : std_logic;
signal we_b : std_logic_vector(7 downto 0);
--
begin
--
address_a <= '1' & address(10 downto 0) & "1111";
instruction <= data_out_a(33 downto 32) & data_out_a(15 downto 0);
data_in_a <= "00000000000000000000000000000000000" & address(11);
--
address_b <= "1111111111111111";
data_in_b <= "00" & data_out_b(33 downto 32) & "0000000000000000" & data_out_b(15 downto 0);
enable_b <= '0';
we_b <= "00000000";
clk_b <= '0';
--
kcpsm6_rom: RAMB36E1
generic map ( READ_WIDTH_A => 18,
WRITE_WIDTH_A => 18,
DOA_REG => 0,
INIT_A => X"000000000",
RSTREG_PRIORITY_A => "REGCE",
SRVAL_A => X"000000000",
WRITE_MODE_A => "WRITE_FIRST",
READ_WIDTH_B => 18,
WRITE_WIDTH_B => 18,
DOB_REG => 0,
INIT_B => X"000000000",
RSTREG_PRIORITY_B => "REGCE",
SRVAL_B => X"000000000",
WRITE_MODE_B => "WRITE_FIRST",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
RAM_MODE => "TDP",
RDADDR_COLLISION_HWCONFIG => "DELAYED_WRITE",
EN_ECC_READ => FALSE,
EN_ECC_WRITE => FALSE,
RAM_EXTENSION_A => "NONE",
RAM_EXTENSION_B => "NONE",
SIM_DEVICE => "VIRTEX6",
INIT_00 => X"{INIT_00}",
INIT_01 => X"{INIT_01}",
INIT_02 => X"{INIT_02}",
INIT_03 => X"{INIT_03}",
INIT_04 => X"{INIT_04}",
INIT_05 => X"{INIT_05}",
INIT_06 => X"{INIT_06}",
INIT_07 => X"{INIT_07}",
INIT_08 => X"{INIT_08}",
INIT_09 => X"{INIT_09}",
INIT_0A => X"{INIT_0A}",
INIT_0B => X"{INIT_0B}",
INIT_0C => X"{INIT_0C}",
INIT_0D => X"{INIT_0D}",
INIT_0E => X"{INIT_0E}",
INIT_0F => X"{INIT_0F}",
INIT_10 => X"{INIT_10}",
INIT_11 => X"{INIT_11}",
INIT_12 => X"{INIT_12}",
INIT_13 => X"{INIT_13}",
INIT_14 => X"{INIT_14}",
INIT_15 => X"{INIT_15}",
INIT_16 => X"{INIT_16}",
INIT_17 => X"{INIT_17}",
INIT_18 => X"{INIT_18}",
INIT_19 => X"{INIT_19}",
INIT_1A => X"{INIT_1A}",
INIT_1B => X"{INIT_1B}",
INIT_1C => X"{INIT_1C}",
INIT_1D => X"{INIT_1D}",
INIT_1E => X"{INIT_1E}",
INIT_1F => X"{INIT_1F}",
INIT_20 => X"{INIT_20}",
INIT_21 => X"{INIT_21}",
INIT_22 => X"{INIT_22}",
INIT_23 => X"{INIT_23}",
INIT_24 => X"{INIT_24}",
INIT_25 => X"{INIT_25}",
INIT_26 => X"{INIT_26}",
INIT_27 => X"{INIT_27}",
INIT_28 => X"{INIT_28}",
INIT_29 => X"{INIT_29}",
INIT_2A => X"{INIT_2A}",
INIT_2B => X"{INIT_2B}",
INIT_2C => X"{INIT_2C}",
INIT_2D => X"{INIT_2D}",
INIT_2E => X"{INIT_2E}",
INIT_2F => X"{INIT_2F}",
INIT_30 => X"{INIT_30}",
INIT_31 => X"{INIT_31}",
INIT_32 => X"{INIT_32}",
INIT_33 => X"{INIT_33}",
INIT_34 => X"{INIT_34}",
INIT_35 => X"{INIT_35}",
INIT_36 => X"{INIT_36}",
INIT_37 => X"{INIT_37}",
INIT_38 => X"{INIT_38}",
INIT_39 => X"{INIT_39}",
INIT_3A => X"{INIT_3A}",
INIT_3B => X"{INIT_3B}",
INIT_3C => X"{INIT_3C}",
INIT_3D => X"{INIT_3D}",
INIT_3E => X"{INIT_3E}",
INIT_3F => X"{INIT_3F}",
INIT_40 => X"{INIT_40}",
INIT_41 => X"{INIT_41}",
INIT_42 => X"{INIT_42}",
INIT_43 => X"{INIT_43}",
INIT_44 => X"{INIT_44}",
INIT_45 => X"{INIT_45}",
INIT_46 => X"{INIT_46}",
INIT_47 => X"{INIT_47}",
INIT_48 => X"{INIT_48}",
INIT_49 => X"{INIT_49}",
INIT_4A => X"{INIT_4A}",
INIT_4B => X"{INIT_4B}",
INIT_4C => X"{INIT_4C}",
INIT_4D => X"{INIT_4D}",
INIT_4E => X"{INIT_4E}",
INIT_4F => X"{INIT_4F}",
INIT_50 => X"{INIT_50}",
INIT_51 => X"{INIT_51}",
INIT_52 => X"{INIT_52}",
INIT_53 => X"{INIT_53}",
INIT_54 => X"{INIT_54}",
INIT_55 => X"{INIT_55}",
INIT_56 => X"{INIT_56}",
INIT_57 => X"{INIT_57}",
INIT_58 => X"{INIT_58}",
INIT_59 => X"{INIT_59}",
INIT_5A => X"{INIT_5A}",
INIT_5B => X"{INIT_5B}",
INIT_5C => X"{INIT_5C}",
INIT_5D => X"{INIT_5D}",
INIT_5E => X"{INIT_5E}",
INIT_5F => X"{INIT_5F}",
INIT_60 => X"{INIT_60}",
INIT_61 => X"{INIT_61}",
INIT_62 => X"{INIT_62}",
INIT_63 => X"{INIT_63}",
INIT_64 => X"{INIT_64}",
INIT_65 => X"{INIT_65}",
INIT_66 => X"{INIT_66}",
INIT_67 => X"{INIT_67}",
INIT_68 => X"{INIT_68}",
INIT_69 => X"{INIT_69}",
INIT_6A => X"{INIT_6A}",
INIT_6B => X"{INIT_6B}",
INIT_6C => X"{INIT_6C}",
INIT_6D => X"{INIT_6D}",
INIT_6E => X"{INIT_6E}",
INIT_6F => X"{INIT_6F}",
INIT_70 => X"{INIT_70}",
INIT_71 => X"{INIT_71}",
INIT_72 => X"{INIT_72}",
INIT_73 => X"{INIT_73}",
INIT_74 => X"{INIT_74}",
INIT_75 => X"{INIT_75}",
INIT_76 => X"{INIT_76}",
INIT_77 => X"{INIT_77}",
INIT_78 => X"{INIT_78}",
INIT_79 => X"{INIT_79}",
INIT_7A => X"{INIT_7A}",
INIT_7B => X"{INIT_7B}",
INIT_7C => X"{INIT_7C}",
INIT_7D => X"{INIT_7D}",
INIT_7E => X"{INIT_7E}",
INIT_7F => X"{INIT_7F}",
INITP_00 => X"{INITP_00}",
INITP_01 => X"{INITP_01}",
INITP_02 => X"{INITP_02}",
INITP_03 => X"{INITP_03}",
INITP_04 => X"{INITP_04}",
INITP_05 => X"{INITP_05}",
INITP_06 => X"{INITP_06}",
INITP_07 => X"{INITP_07}",
INITP_08 => X"{INITP_08}",
INITP_09 => X"{INITP_09}",
INITP_0A => X"{INITP_0A}",
INITP_0B => X"{INITP_0B}",
INITP_0C => X"{INITP_0C}",
INITP_0D => X"{INITP_0D}",
INITP_0E => X"{INITP_0E}",
INITP_0F => X"{INITP_0F}")
port map( ADDRARDADDR => address_a,
ENARDEN => enable,
CLKARDCLK => clk,
DOADO => data_out_a(31 downto 0),
DOPADOP => data_out_a(35 downto 32),
DIADI => data_in_a(31 downto 0),
DIPADIP => data_in_a(35 downto 32),
WEA => "0000",
REGCEAREGCE => '0',
RSTRAMARSTRAM => '0',
RSTREGARSTREG => '0',
ADDRBWRADDR => address_b,
ENBWREN => enable_b,
CLKBWRCLK => clk_b,
DOBDO => data_out_b(31 downto 0),
DOPBDOP => data_out_b(35 downto 32),
DIBDI => data_in_b(31 downto 0),
DIPBDIP => data_in_b(35 downto 32),
WEBWE => we_b,
REGCEB => '0',
RSTRAMB => '0',
RSTREGB => '0',
CASCADEINA => '0',
CASCADEINB => '0',
INJECTDBITERR => '0',
INJECTSBITERR => '0');
--
--
end low_level_definition;
--
------------------------------------------------------------------------------------
--
-- END OF FILE {name}.vhd
--
------------------------------------------------------------------------------------

View File

@ -0,0 +1,564 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
ROM_form.vhd
Production template for a 4K program for KCPSM6 in a Virtex-6 device using
2 x RAMB36E1 primitives.
Ken Chapman (Xilinx Ltd)
5th August 2011 - First Release
14th March 2013 - Unused address inputs on BRAMs connected High to reflect
descriptions UG363.
This is a VHDL template file for the KCPSM6 assembler.
This VHDL file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.vhd' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the VHDL.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2010-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
--
-- Production definition of a 4K program for KCPSM6 in a Virtex-6 device using
-- 2 x RAMB36E1 primitives.
--
--
-- Program defined by '{psmname}.psm'.
--
-- Generated by KCPSM6 Assembler: {timestamp}.
--
-- Assembler used ROM_form template: ROM_form_V6_4K_14March13.vhd
--
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
--
entity {name} is
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
clk : in std_logic);
end {name};
--
architecture low_level_definition of {name} is
--
signal address_a : std_logic_vector(15 downto 0);
signal data_in_a : std_logic_vector(35 downto 0);
signal data_out_a_l : std_logic_vector(35 downto 0);
signal data_out_a_h : std_logic_vector(35 downto 0);
signal address_b : std_logic_vector(15 downto 0);
signal data_in_b_l : std_logic_vector(35 downto 0);
signal data_out_b_l : std_logic_vector(35 downto 0);
signal data_in_b_h : std_logic_vector(35 downto 0);
signal data_out_b_h : std_logic_vector(35 downto 0);
signal enable_b : std_logic;
signal clk_b : std_logic;
signal we_b : std_logic_vector(7 downto 0);
--
begin
--
address_a <= '1' & address(11 downto 0) & "111";
instruction <= data_out_a_h(32) & data_out_a_h(7 downto 0) & data_out_a_l(32) & data_out_a_l(7 downto 0);
data_in_a <= "000000000000000000000000000000000000";
--
address_b <= "1111111111111111";
data_in_b_l <= "000" & data_out_b_l(32) & "000000000000000000000000" & data_out_b_l(7 downto 0);
data_in_b_h <= "000" & data_out_b_h(32) & "000000000000000000000000" & data_out_b_h(7 downto 0);
enable_b <= '0';
we_b <= "00000000";
clk_b <= '0';
--
kcpsm6_rom_l: RAMB36E1
generic map ( READ_WIDTH_A => 9,
WRITE_WIDTH_A => 9,
DOA_REG => 0,
INIT_A => X"000000000",
RSTREG_PRIORITY_A => "REGCE",
SRVAL_A => X"000000000",
WRITE_MODE_A => "WRITE_FIRST",
READ_WIDTH_B => 9,
WRITE_WIDTH_B => 9,
DOB_REG => 0,
INIT_B => X"000000000",
RSTREG_PRIORITY_B => "REGCE",
SRVAL_B => X"000000000",
WRITE_MODE_B => "WRITE_FIRST",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
RAM_MODE => "TDP",
RDADDR_COLLISION_HWCONFIG => "DELAYED_WRITE",
EN_ECC_READ => FALSE,
EN_ECC_WRITE => FALSE,
RAM_EXTENSION_A => "NONE",
RAM_EXTENSION_B => "NONE",
SIM_DEVICE => "VIRTEX6",
INIT_00 => X"{[8:0]_INIT_00}",
INIT_01 => X"{[8:0]_INIT_01}",
INIT_02 => X"{[8:0]_INIT_02}",
INIT_03 => X"{[8:0]_INIT_03}",
INIT_04 => X"{[8:0]_INIT_04}",
INIT_05 => X"{[8:0]_INIT_05}",
INIT_06 => X"{[8:0]_INIT_06}",
INIT_07 => X"{[8:0]_INIT_07}",
INIT_08 => X"{[8:0]_INIT_08}",
INIT_09 => X"{[8:0]_INIT_09}",
INIT_0A => X"{[8:0]_INIT_0A}",
INIT_0B => X"{[8:0]_INIT_0B}",
INIT_0C => X"{[8:0]_INIT_0C}",
INIT_0D => X"{[8:0]_INIT_0D}",
INIT_0E => X"{[8:0]_INIT_0E}",
INIT_0F => X"{[8:0]_INIT_0F}",
INIT_10 => X"{[8:0]_INIT_10}",
INIT_11 => X"{[8:0]_INIT_11}",
INIT_12 => X"{[8:0]_INIT_12}",
INIT_13 => X"{[8:0]_INIT_13}",
INIT_14 => X"{[8:0]_INIT_14}",
INIT_15 => X"{[8:0]_INIT_15}",
INIT_16 => X"{[8:0]_INIT_16}",
INIT_17 => X"{[8:0]_INIT_17}",
INIT_18 => X"{[8:0]_INIT_18}",
INIT_19 => X"{[8:0]_INIT_19}",
INIT_1A => X"{[8:0]_INIT_1A}",
INIT_1B => X"{[8:0]_INIT_1B}",
INIT_1C => X"{[8:0]_INIT_1C}",
INIT_1D => X"{[8:0]_INIT_1D}",
INIT_1E => X"{[8:0]_INIT_1E}",
INIT_1F => X"{[8:0]_INIT_1F}",
INIT_20 => X"{[8:0]_INIT_20}",
INIT_21 => X"{[8:0]_INIT_21}",
INIT_22 => X"{[8:0]_INIT_22}",
INIT_23 => X"{[8:0]_INIT_23}",
INIT_24 => X"{[8:0]_INIT_24}",
INIT_25 => X"{[8:0]_INIT_25}",
INIT_26 => X"{[8:0]_INIT_26}",
INIT_27 => X"{[8:0]_INIT_27}",
INIT_28 => X"{[8:0]_INIT_28}",
INIT_29 => X"{[8:0]_INIT_29}",
INIT_2A => X"{[8:0]_INIT_2A}",
INIT_2B => X"{[8:0]_INIT_2B}",
INIT_2C => X"{[8:0]_INIT_2C}",
INIT_2D => X"{[8:0]_INIT_2D}",
INIT_2E => X"{[8:0]_INIT_2E}",
INIT_2F => X"{[8:0]_INIT_2F}",
INIT_30 => X"{[8:0]_INIT_30}",
INIT_31 => X"{[8:0]_INIT_31}",
INIT_32 => X"{[8:0]_INIT_32}",
INIT_33 => X"{[8:0]_INIT_33}",
INIT_34 => X"{[8:0]_INIT_34}",
INIT_35 => X"{[8:0]_INIT_35}",
INIT_36 => X"{[8:0]_INIT_36}",
INIT_37 => X"{[8:0]_INIT_37}",
INIT_38 => X"{[8:0]_INIT_38}",
INIT_39 => X"{[8:0]_INIT_39}",
INIT_3A => X"{[8:0]_INIT_3A}",
INIT_3B => X"{[8:0]_INIT_3B}",
INIT_3C => X"{[8:0]_INIT_3C}",
INIT_3D => X"{[8:0]_INIT_3D}",
INIT_3E => X"{[8:0]_INIT_3E}",
INIT_3F => X"{[8:0]_INIT_3F}",
INIT_40 => X"{[8:0]_INIT_40}",
INIT_41 => X"{[8:0]_INIT_41}",
INIT_42 => X"{[8:0]_INIT_42}",
INIT_43 => X"{[8:0]_INIT_43}",
INIT_44 => X"{[8:0]_INIT_44}",
INIT_45 => X"{[8:0]_INIT_45}",
INIT_46 => X"{[8:0]_INIT_46}",
INIT_47 => X"{[8:0]_INIT_47}",
INIT_48 => X"{[8:0]_INIT_48}",
INIT_49 => X"{[8:0]_INIT_49}",
INIT_4A => X"{[8:0]_INIT_4A}",
INIT_4B => X"{[8:0]_INIT_4B}",
INIT_4C => X"{[8:0]_INIT_4C}",
INIT_4D => X"{[8:0]_INIT_4D}",
INIT_4E => X"{[8:0]_INIT_4E}",
INIT_4F => X"{[8:0]_INIT_4F}",
INIT_50 => X"{[8:0]_INIT_50}",
INIT_51 => X"{[8:0]_INIT_51}",
INIT_52 => X"{[8:0]_INIT_52}",
INIT_53 => X"{[8:0]_INIT_53}",
INIT_54 => X"{[8:0]_INIT_54}",
INIT_55 => X"{[8:0]_INIT_55}",
INIT_56 => X"{[8:0]_INIT_56}",
INIT_57 => X"{[8:0]_INIT_57}",
INIT_58 => X"{[8:0]_INIT_58}",
INIT_59 => X"{[8:0]_INIT_59}",
INIT_5A => X"{[8:0]_INIT_5A}",
INIT_5B => X"{[8:0]_INIT_5B}",
INIT_5C => X"{[8:0]_INIT_5C}",
INIT_5D => X"{[8:0]_INIT_5D}",
INIT_5E => X"{[8:0]_INIT_5E}",
INIT_5F => X"{[8:0]_INIT_5F}",
INIT_60 => X"{[8:0]_INIT_60}",
INIT_61 => X"{[8:0]_INIT_61}",
INIT_62 => X"{[8:0]_INIT_62}",
INIT_63 => X"{[8:0]_INIT_63}",
INIT_64 => X"{[8:0]_INIT_64}",
INIT_65 => X"{[8:0]_INIT_65}",
INIT_66 => X"{[8:0]_INIT_66}",
INIT_67 => X"{[8:0]_INIT_67}",
INIT_68 => X"{[8:0]_INIT_68}",
INIT_69 => X"{[8:0]_INIT_69}",
INIT_6A => X"{[8:0]_INIT_6A}",
INIT_6B => X"{[8:0]_INIT_6B}",
INIT_6C => X"{[8:0]_INIT_6C}",
INIT_6D => X"{[8:0]_INIT_6D}",
INIT_6E => X"{[8:0]_INIT_6E}",
INIT_6F => X"{[8:0]_INIT_6F}",
INIT_70 => X"{[8:0]_INIT_70}",
INIT_71 => X"{[8:0]_INIT_71}",
INIT_72 => X"{[8:0]_INIT_72}",
INIT_73 => X"{[8:0]_INIT_73}",
INIT_74 => X"{[8:0]_INIT_74}",
INIT_75 => X"{[8:0]_INIT_75}",
INIT_76 => X"{[8:0]_INIT_76}",
INIT_77 => X"{[8:0]_INIT_77}",
INIT_78 => X"{[8:0]_INIT_78}",
INIT_79 => X"{[8:0]_INIT_79}",
INIT_7A => X"{[8:0]_INIT_7A}",
INIT_7B => X"{[8:0]_INIT_7B}",
INIT_7C => X"{[8:0]_INIT_7C}",
INIT_7D => X"{[8:0]_INIT_7D}",
INIT_7E => X"{[8:0]_INIT_7E}",
INIT_7F => X"{[8:0]_INIT_7F}",
INITP_00 => X"{[8:0]_INITP_00}",
INITP_01 => X"{[8:0]_INITP_01}",
INITP_02 => X"{[8:0]_INITP_02}",
INITP_03 => X"{[8:0]_INITP_03}",
INITP_04 => X"{[8:0]_INITP_04}",
INITP_05 => X"{[8:0]_INITP_05}",
INITP_06 => X"{[8:0]_INITP_06}",
INITP_07 => X"{[8:0]_INITP_07}",
INITP_08 => X"{[8:0]_INITP_08}",
INITP_09 => X"{[8:0]_INITP_09}",
INITP_0A => X"{[8:0]_INITP_0A}",
INITP_0B => X"{[8:0]_INITP_0B}",
INITP_0C => X"{[8:0]_INITP_0C}",
INITP_0D => X"{[8:0]_INITP_0D}",
INITP_0E => X"{[8:0]_INITP_0E}",
INITP_0F => X"{[8:0]_INITP_0F}")
port map( ADDRARDADDR => address_a,
ENARDEN => enable,
CLKARDCLK => clk,
DOADO => data_out_a_l(31 downto 0),
DOPADOP => data_out_a_l(35 downto 32),
DIADI => data_in_a(31 downto 0),
DIPADIP => data_in_a(35 downto 32),
WEA => "0000",
REGCEAREGCE => '0',
RSTRAMARSTRAM => '0',
RSTREGARSTREG => '0',
ADDRBWRADDR => address_b,
ENBWREN => enable_b,
CLKBWRCLK => clk_b,
DOBDO => data_out_b_l(31 downto 0),
DOPBDOP => data_out_b_l(35 downto 32),
DIBDI => data_in_b_l(31 downto 0),
DIPBDIP => data_in_b_l(35 downto 32),
WEBWE => we_b,
REGCEB => '0',
RSTRAMB => '0',
RSTREGB => '0',
CASCADEINA => '0',
CASCADEINB => '0',
INJECTDBITERR => '0',
INJECTSBITERR => '0');
--
kcpsm6_rom_h: RAMB36E1
generic map ( READ_WIDTH_A => 9,
WRITE_WIDTH_A => 9,
DOA_REG => 0,
INIT_A => X"000000000",
RSTREG_PRIORITY_A => "REGCE",
SRVAL_A => X"000000000",
WRITE_MODE_A => "WRITE_FIRST",
READ_WIDTH_B => 9,
WRITE_WIDTH_B => 9,
DOB_REG => 0,
INIT_B => X"000000000",
RSTREG_PRIORITY_B => "REGCE",
SRVAL_B => X"000000000",
WRITE_MODE_B => "WRITE_FIRST",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
RAM_MODE => "TDP",
RDADDR_COLLISION_HWCONFIG => "DELAYED_WRITE",
EN_ECC_READ => FALSE,
EN_ECC_WRITE => FALSE,
RAM_EXTENSION_A => "NONE",
RAM_EXTENSION_B => "NONE",
SIM_DEVICE => "VIRTEX6",
INIT_00 => X"{[17:9]_INIT_00}",
INIT_01 => X"{[17:9]_INIT_01}",
INIT_02 => X"{[17:9]_INIT_02}",
INIT_03 => X"{[17:9]_INIT_03}",
INIT_04 => X"{[17:9]_INIT_04}",
INIT_05 => X"{[17:9]_INIT_05}",
INIT_06 => X"{[17:9]_INIT_06}",
INIT_07 => X"{[17:9]_INIT_07}",
INIT_08 => X"{[17:9]_INIT_08}",
INIT_09 => X"{[17:9]_INIT_09}",
INIT_0A => X"{[17:9]_INIT_0A}",
INIT_0B => X"{[17:9]_INIT_0B}",
INIT_0C => X"{[17:9]_INIT_0C}",
INIT_0D => X"{[17:9]_INIT_0D}",
INIT_0E => X"{[17:9]_INIT_0E}",
INIT_0F => X"{[17:9]_INIT_0F}",
INIT_10 => X"{[17:9]_INIT_10}",
INIT_11 => X"{[17:9]_INIT_11}",
INIT_12 => X"{[17:9]_INIT_12}",
INIT_13 => X"{[17:9]_INIT_13}",
INIT_14 => X"{[17:9]_INIT_14}",
INIT_15 => X"{[17:9]_INIT_15}",
INIT_16 => X"{[17:9]_INIT_16}",
INIT_17 => X"{[17:9]_INIT_17}",
INIT_18 => X"{[17:9]_INIT_18}",
INIT_19 => X"{[17:9]_INIT_19}",
INIT_1A => X"{[17:9]_INIT_1A}",
INIT_1B => X"{[17:9]_INIT_1B}",
INIT_1C => X"{[17:9]_INIT_1C}",
INIT_1D => X"{[17:9]_INIT_1D}",
INIT_1E => X"{[17:9]_INIT_1E}",
INIT_1F => X"{[17:9]_INIT_1F}",
INIT_20 => X"{[17:9]_INIT_20}",
INIT_21 => X"{[17:9]_INIT_21}",
INIT_22 => X"{[17:9]_INIT_22}",
INIT_23 => X"{[17:9]_INIT_23}",
INIT_24 => X"{[17:9]_INIT_24}",
INIT_25 => X"{[17:9]_INIT_25}",
INIT_26 => X"{[17:9]_INIT_26}",
INIT_27 => X"{[17:9]_INIT_27}",
INIT_28 => X"{[17:9]_INIT_28}",
INIT_29 => X"{[17:9]_INIT_29}",
INIT_2A => X"{[17:9]_INIT_2A}",
INIT_2B => X"{[17:9]_INIT_2B}",
INIT_2C => X"{[17:9]_INIT_2C}",
INIT_2D => X"{[17:9]_INIT_2D}",
INIT_2E => X"{[17:9]_INIT_2E}",
INIT_2F => X"{[17:9]_INIT_2F}",
INIT_30 => X"{[17:9]_INIT_30}",
INIT_31 => X"{[17:9]_INIT_31}",
INIT_32 => X"{[17:9]_INIT_32}",
INIT_33 => X"{[17:9]_INIT_33}",
INIT_34 => X"{[17:9]_INIT_34}",
INIT_35 => X"{[17:9]_INIT_35}",
INIT_36 => X"{[17:9]_INIT_36}",
INIT_37 => X"{[17:9]_INIT_37}",
INIT_38 => X"{[17:9]_INIT_38}",
INIT_39 => X"{[17:9]_INIT_39}",
INIT_3A => X"{[17:9]_INIT_3A}",
INIT_3B => X"{[17:9]_INIT_3B}",
INIT_3C => X"{[17:9]_INIT_3C}",
INIT_3D => X"{[17:9]_INIT_3D}",
INIT_3E => X"{[17:9]_INIT_3E}",
INIT_3F => X"{[17:9]_INIT_3F}",
INIT_40 => X"{[17:9]_INIT_40}",
INIT_41 => X"{[17:9]_INIT_41}",
INIT_42 => X"{[17:9]_INIT_42}",
INIT_43 => X"{[17:9]_INIT_43}",
INIT_44 => X"{[17:9]_INIT_44}",
INIT_45 => X"{[17:9]_INIT_45}",
INIT_46 => X"{[17:9]_INIT_46}",
INIT_47 => X"{[17:9]_INIT_47}",
INIT_48 => X"{[17:9]_INIT_48}",
INIT_49 => X"{[17:9]_INIT_49}",
INIT_4A => X"{[17:9]_INIT_4A}",
INIT_4B => X"{[17:9]_INIT_4B}",
INIT_4C => X"{[17:9]_INIT_4C}",
INIT_4D => X"{[17:9]_INIT_4D}",
INIT_4E => X"{[17:9]_INIT_4E}",
INIT_4F => X"{[17:9]_INIT_4F}",
INIT_50 => X"{[17:9]_INIT_50}",
INIT_51 => X"{[17:9]_INIT_51}",
INIT_52 => X"{[17:9]_INIT_52}",
INIT_53 => X"{[17:9]_INIT_53}",
INIT_54 => X"{[17:9]_INIT_54}",
INIT_55 => X"{[17:9]_INIT_55}",
INIT_56 => X"{[17:9]_INIT_56}",
INIT_57 => X"{[17:9]_INIT_57}",
INIT_58 => X"{[17:9]_INIT_58}",
INIT_59 => X"{[17:9]_INIT_59}",
INIT_5A => X"{[17:9]_INIT_5A}",
INIT_5B => X"{[17:9]_INIT_5B}",
INIT_5C => X"{[17:9]_INIT_5C}",
INIT_5D => X"{[17:9]_INIT_5D}",
INIT_5E => X"{[17:9]_INIT_5E}",
INIT_5F => X"{[17:9]_INIT_5F}",
INIT_60 => X"{[17:9]_INIT_60}",
INIT_61 => X"{[17:9]_INIT_61}",
INIT_62 => X"{[17:9]_INIT_62}",
INIT_63 => X"{[17:9]_INIT_63}",
INIT_64 => X"{[17:9]_INIT_64}",
INIT_65 => X"{[17:9]_INIT_65}",
INIT_66 => X"{[17:9]_INIT_66}",
INIT_67 => X"{[17:9]_INIT_67}",
INIT_68 => X"{[17:9]_INIT_68}",
INIT_69 => X"{[17:9]_INIT_69}",
INIT_6A => X"{[17:9]_INIT_6A}",
INIT_6B => X"{[17:9]_INIT_6B}",
INIT_6C => X"{[17:9]_INIT_6C}",
INIT_6D => X"{[17:9]_INIT_6D}",
INIT_6E => X"{[17:9]_INIT_6E}",
INIT_6F => X"{[17:9]_INIT_6F}",
INIT_70 => X"{[17:9]_INIT_70}",
INIT_71 => X"{[17:9]_INIT_71}",
INIT_72 => X"{[17:9]_INIT_72}",
INIT_73 => X"{[17:9]_INIT_73}",
INIT_74 => X"{[17:9]_INIT_74}",
INIT_75 => X"{[17:9]_INIT_75}",
INIT_76 => X"{[17:9]_INIT_76}",
INIT_77 => X"{[17:9]_INIT_77}",
INIT_78 => X"{[17:9]_INIT_78}",
INIT_79 => X"{[17:9]_INIT_79}",
INIT_7A => X"{[17:9]_INIT_7A}",
INIT_7B => X"{[17:9]_INIT_7B}",
INIT_7C => X"{[17:9]_INIT_7C}",
INIT_7D => X"{[17:9]_INIT_7D}",
INIT_7E => X"{[17:9]_INIT_7E}",
INIT_7F => X"{[17:9]_INIT_7F}",
INITP_00 => X"{[17:9]_INITP_00}",
INITP_01 => X"{[17:9]_INITP_01}",
INITP_02 => X"{[17:9]_INITP_02}",
INITP_03 => X"{[17:9]_INITP_03}",
INITP_04 => X"{[17:9]_INITP_04}",
INITP_05 => X"{[17:9]_INITP_05}",
INITP_06 => X"{[17:9]_INITP_06}",
INITP_07 => X"{[17:9]_INITP_07}",
INITP_08 => X"{[17:9]_INITP_08}",
INITP_09 => X"{[17:9]_INITP_09}",
INITP_0A => X"{[17:9]_INITP_0A}",
INITP_0B => X"{[17:9]_INITP_0B}",
INITP_0C => X"{[17:9]_INITP_0C}",
INITP_0D => X"{[17:9]_INITP_0D}",
INITP_0E => X"{[17:9]_INITP_0E}",
INITP_0F => X"{[17:9]_INITP_0F}")
port map( ADDRARDADDR => address_a,
ENARDEN => enable,
CLKARDCLK => clk,
DOADO => data_out_a_h(31 downto 0),
DOPADOP => data_out_a_h(35 downto 32),
DIADI => data_in_a(31 downto 0),
DIPADIP => data_in_a(35 downto 32),
WEA => "0000",
REGCEAREGCE => '0',
RSTRAMARSTRAM => '0',
RSTREGARSTREG => '0',
ADDRBWRADDR => address_b,
ENBWREN => enable_b,
CLKBWRCLK => clk_b,
DOBDO => data_out_b_h(31 downto 0),
DOPBDOP => data_out_b_h(35 downto 32),
DIBDI => data_in_b_h(31 downto 0),
DIPBDIP => data_in_b_h(35 downto 32),
WEBWE => we_b,
REGCEB => '0',
RSTRAMB => '0',
RSTREGB => '0',
CASCADEINA => '0',
CASCADEINB => '0',
INJECTDBITERR => '0',
INJECTSBITERR => '0');
--
end low_level_definition;
--
------------------------------------------------------------------------------------
--
-- END OF FILE {name}.vhd
--
------------------------------------------------------------------------------------

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,509 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2011-2012, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; PicoBlaze Reference Design.
;
;
; Routines for General Purpose I2C Communication
;
; Ken Chapman - Xilinx Ltd
;
; 9th March 2012 - Initial Version
; 12th October 2012 - Adjustments to values assigned to constant directives
; 16th October 2012 - Code optimisation (lowest level signal drive routines)
; 25th October 2012 - Correct definition of a binary value (functionally identical)
; 6th November 2012 - Correction to comment only
;
;
; NOTE - This is not a standalone PSM file. Include this file in a program that
; then calls these routines and works with the values in scratch pad memory.
;
; INCLUDE "i2c_routines.psm"
;
;
; IMPORTANT - These routines interact with input and output ports which must
; be appropriately defined to drive and read the physical I2C
; signals. Four CONSTANT directives must define values consistent
; with your port definitions and a further CONSTANT must be defined
; that is related to the frequency of the clock being applied to
; KCPSM6 in your design (Please see descriptions below).
;
;
; INTRODUCTION
; ------------
;
; The following routines implement an I2C 'Master' with a communication data rate
; approaching (but not exceeding) 100KHz. The I2C bus connects to the FPGA I/O
; pins which must in turn be connected to KCPSM6 input and output ports. Therefore
; your hardware design must be appropriate before these routines can be used and
; these routines need to know which ports you have allocated for I2C in your design.
;
; With the hardware in place, the routines provide the ability to perform each of the
; actions generally required for an I2C transaction including bus idle, Start (S),
; Repeated Start (Sr), Stop (P), Transmission of Acknowledge (ACK) or No Acknowledge
; (NACK), receiving and testing of Acknowledge (ACK) from a slave and of course the
; ability to transmit and receive bytes used for addressing, commands and data.
;
; It is assumed that you are familiar with I2C, so the descriptions contained in this
; file are concerned primarily with how KCPSM6 is used to implement the signaling and
; elements of the transactions rather than to teach I2C itself. In the end, it is the
; sequence in which these routines are invoked that will result in successful
; communication with a slave device and that requires an understanding of the needs
; of each particular slave to implement correctly (i.e. a study of data sheets for
; slave devices when writing higher level code).
;
; NOTE - As provided, these routines assume that KCPSM6 is the only I2C master connected
; to the bus. A multiple master implementation would be possible but these routines
; are not suitable in such arrangements.
;
;
;
; Code typical of an I2C write of data to a slave using the routines provided...
;
; CALL I2C_initialise
; CALL I2C_start
; LOAD s5, slave_address ;7-bit slave address
; SL0 s5 ;Write operation signified by LSB = 0
; CALL I2C_Tx_byte
; CALL I2C_Rx_ACK
; JUMP C, communication_fail ;did the slave respond?
; LOAD s5, data_byte1
; CALL I2C_Tx_byte
; CALL I2C_Rx_ACK
; LOAD s5, data_byte2
; CALL I2C_Tx_byte
; CALL I2C_Rx_ACK
; CALL I2C_stop
;
;
; Code typical of an I2C read of data from a slave using the routines provided...
;
; CALL I2C_initialise
; CALL I2C_start
; LOAD s5, slave_address ;7-bit slave address
; SL0 s5 ;Write operation signified by LSB = 0
; CALL I2C_Tx_byte
; CALL I2C_Rx_ACK
; JUMP C, communication_fail ;did the slave respond?
; LOAD s5, slave_command
; CALL I2C_Tx_byte
; CALL I2C_Rx_ACK
; CALL I2C_start ;bus restart (Sr)
; LOAD s5, slave_address ;7-bit slave address
; SL1 s5 ;Read operation signified by LSB = 1
; CALL I2C_Tx_byte
; CALL I2C_Rx_ACK
; CALL I2C_Rx_byte
; STORE s5, data1
; CALL I2C_Tx_ACK
; CALL I2C_Rx_byte
; STORE s5, data2
; CALL I2C_Tx_NACK ;transmit NACK before Stop
; CALL I2C_stop
;
;
;------------------------------------------------------------------------------------------
; Hardware
;------------------------------------------------------------------------------------------
;
; Clock
; -----
;
; All KCPSM6 instructions take 2 clock cycles to execute and it is this predictability
; that these routines exploit to ensure that the I2C communication rate does not exceed
; 100KHz. However, these routines will only implement the correct timing if something
; related to the frequency of the clock provide to KCPSM6 is known and the CONSTANT
; directive below must be defined correctly to achieve that.
;
CONSTANT I2C_time_reference, 24'd
;
; I2C_time_reference = ( fclk - 6 ) / 4
;
; Where...
; 'fclk' is the clock frequency applied to KCPSM6 in MHz.
; Any non-integer result should be rounded up.
; Typical values....
;
; fclk (MHz) I2C_time_reference
; 50 11'd
; 80 19'd
; 100 24'd
; 200 49'd
;
;
;
; I2C Bus and KCPSM6 ports
; ------------------------
;
; An I2C bus consists of two signals called 'CLK' and 'DATA' or something similar. Both
; signals need to be connected to the FPGA via 'open collector' style bidirectional I/O
; pins with a pull-up resistor (typically an external resistor but the built in pull-up
; resistor of the IOB may also be enabled in some cases). These I/O pins must then be
; connected to a KCPSM6 input port and KCPSM6 output port such that both signals can
; be both driven and read.
;
; The input port used to read the logic levels on the CLK and DATA signals external
; to the FPGA.
;
; The output port is used to control the output drive of the CLK and DATA pins.
; Since the pins are 'open collector' style then when KCPSM6 outputs...
; '0' will result in the signal being driven Low.
; '1' will result in the pin becoming tri-state (Z) so the signal will be pulled
; High by the resistor or can be driven or held low by a slave device.
;
; In a typical VHDL based design the following snippets of code could be inserted at the
; appropriate places to define the I2C pins and connection to KCPSM6...
;
; entity <name>
; Port ( i2c_clk : inout std_logic;
; i2c_data : inout std_logic;
;
;
; signal drive_i2c_clk : std_logic;
; signal drive_i2c_data : std_logic;
;
;
; i2c_clk <= '0' when drive_i2c_clk = '0' else 'Z';
; i2c_data <= '0' when drive_i2c_data = '0' else 'Z';
;
;
; input_ports: process(clk)
; begin
; if clk'event and clk = '1' then
; case port_id(1 downto 0) is
;
; -- Read I2C Bus at port address 02 hex
; when "10" => in_port(0) <= i2c_clk;
; in_port(1) <= i2c_data;
;
;
; output_ports: process(clk)
; begin
; if clk'event and clk = '1' then
; if write_strobe = '1' then
;
; -- Write to I2C Bus at port address 08 hex
; if port_id(3) = '1' then
; drive_i2c_clk <= out_port(0);
; drive_i2c_data <= out_port(1);
; end if;
;
;
;
; To correspond with the definition of the input and output ports, the four CONSTANT
; directives below must be set correctly before these I2C routines are used. The
; values shown below correspond with the VHDL snippets above.
;
CONSTANT I2C_input_port, 02 ;port address of I2C input port
CONSTANT I2C_output_port, 08 ;port address of I2C output port
;
CONSTANT I2C_clk, 00000001'b ;Bit to which CLK is assigned on both ports
CONSTANT I2C_data, 00000010'b ;Bit to which DATA is assigned on both ports
;
;
;------------------------------------------------------------------------------------------
; Registers
;------------------------------------------------------------------------------------------
;
; The following registers within the currently active bank are used by these routines....
;
; s0, s1, s5 and sF
;
;
; IMPORTANT - Register 'sF' is used to control and remember the drive values of the CLK
; and DATA signals so its contents MUST NOT be altered between calls to the
; various routines used to construct a complete I2C transaction. The routine
; called 'I2C_initialise' is typically used before starting any transaction
; as it will initialise 'sF' as well as the actual I2C interface.
;
;
;------------------------------------------------------------------------------------------
; Routine to initialise the CLK and DATA signals (and 'sF')
;------------------------------------------------------------------------------------------
;
; Places CLK and DATA into tri-state (Z) so that both lines reach idle High level.
; This also initialises register sF ready for other routines forming a transaction.
;
; This routine MUST be used before starting the first I2C transaction and before any
; further transaction if the contents of register 'sF' have been compromised since the
; end of the last I2C transaction.
;
I2C_initialise: LOAD sF, I2C_clk ;CLK = Z
OR sF, I2C_data ;DATA = Z
OUTPUT sF, I2C_output_port
RETURN
;
;
;------------------------------------------------------------------------------------------
; Routine issue an I2C Start (S) or Repeated Start (Sr) condition.
;------------------------------------------------------------------------------------------
;
; Used to begin any I2C transaction or performed during a transaction when changing the
; from an write to a read.
;
; The Start (S) or Repeated Start (Sr) condition is signified by a High to Low transition
; of the DATA line whilst the CLK line is High.
;
I2C_start: CALL I2C_data_Z ;DATA = Z (High)
CALL I2C_clk_Z ;CLK = Z (waits until definitely High)
CALL I2C_delay_5us ;delay before start (S)
CALL I2C_data_Low ;High to How transition on DATA whilst CLK is High
CALL I2C_delay_4us
CALL I2C_clk_Low ;CLK = 0 (plus 5us delay)
RETURN
;
;
;------------------------------------------------------------------------------------------
; Routine issue an I2C Stop (P) condition
;------------------------------------------------------------------------------------------
;
; Used to end any I2C transaction.
;
; The Stop (S) condition is signified by a Low to High transition of the DATA line whilst
; the CLK line is High.
;
; Note that following this routine the CARRY flag is '0' and can be used to confirm a
; good I2C communication (see 'I2C_Rx_ACK' routine).
;
I2C_stop: CALL I2C_data_Low ;DATA = 0
CALL I2C_delay_5us
CALL I2C_clk_Z ;CLK = Z (waits until definitely High)
CALL I2C_delay_4us
CALL I2C_data_Z ;DATA = Z (High)
RETURN
;
;
;------------------------------------------------------------------------------------------
; Routine to transmit one byte from the KCPSM6 master to a slave
;------------------------------------------------------------------------------------------
;
; The byte to be transmitted must be provided in register 's5'.
;
; The byte is transmitted most significant bit (MSB) first. As each of the 8 bits are
; presented to the DATA line the CLK line is pulsed High.
;
I2C_Tx_byte: LOAD s1, 10000000'b ;8-bits to transmit starting with MSB
I2C_Tx_next_bit: TEST s5, s1 ;test data bit for High or Low
JUMP NZ, I2C_Tx1
CALL I2C_data_Low ;DATA = 0
JUMP I2C_Tx_tsu
I2C_Tx1: CALL I2C_data_Z ;DATA = Z (High)
I2C_Tx_tsu: CALL I2C_clk_pulse ;generate clock pulse with delays
SR0 s1 ;move to next bit
RETURN C ;have 8 bits been transmitted?
JUMP I2C_Tx_next_bit
;
;
;------------------------------------------------------------------------------------------
; Routine to receive one byte from a slave
;------------------------------------------------------------------------------------------
;
; The byte received will be returned in register 's5'.
;
; The byte is received most significant bit (MSB) first. Each of the 8 bits are sampled
; as the CLK line is pulsed High.
;
I2C_Rx_byte: LOAD s1, 8'd ;8-bits to receive
I2C_Rx_next_bit: CALL I2C_Rx_bit ;receive and shift bit into LSB of s5
SUB s1, 1'd ;count bits received
JUMP NZ, I2C_Rx_next_bit
RETURN
;
;
;------------------------------------------------------------------------------------------
; Routine to transmit Acknowledge (ACK) from KCPSM6 master to a slave
;------------------------------------------------------------------------------------------
;
; An Acknowledge (ACK) bit is transmitted to a slave after receiving a byte of data.
;
; ACK is simply the transmission of a '0' requiring the DATA line to be driven Low whilst
; the CLK line is pulsed High.
;
I2C_Tx_ACK: CALL I2C_data_Low ;DATA = 0
;
I2C_clk_pulse: CALL I2C_delay_5us
CALL I2C_clk_Z ;CLK = Z (waits until definitely High)
CALL I2C_delay_4us ;clock pulse width
CALL I2C_clk_Low ;end of CLK clock pulse includes 5us delay
RETURN
;
;
;------------------------------------------------------------------------------------------
; Routine to transmit No Acknowledge (NACK) from KCPSM6 master to a slave
;------------------------------------------------------------------------------------------
;
; A No Acknowledge (NACK) bit is transmitted to a slave after receiving a byte of data and
; typically used to signify to a slave that a read transaction has been completed.
;
; NACK is simply the transmission of a '1' requiring the DATA line to be driven High
; whilst the CLK line is pulsed High.
;
I2C_Tx_NACK: CALL I2C_data_Z ;DATA = Z (High)
JUMP I2C_clk_pulse ;generate clock pulse (includes return)
;
;
;------------------------------------------------------------------------------------------
; Routine to receive and test the Acknowledge (ACK) from a slave
;------------------------------------------------------------------------------------------
;
; The KCPSM6 master will receive an Acknowledge (ACK) bit from a slave following the
; transmitted of a byte to the slave. Receiving an ACK indicates that the slave responded
; as expected but receiving a No Acknowledge (NACK) implies that something went wrong!
;
; The KCPSM6 master will pulse the CLK line High and receive the acknowledge bit from the
; slave. The received ACK bit will be returned in the least significant bit (LSB) of the
; 's5' register. Furthermore, a test will be performed such that the CARRY flag will also
; reveal if the bit was ACK or NACK.
;
; Received ACK bit Meaning CARRY(C)
; 0 ACK 0
; 1 NACK 1
;
; Note that following the 'I2C_stop' routine the CARRY flag is '0'.
;
I2C_Rx_ACK: CALL I2C_Rx_bit ;receive ACK bit into LSB of s5
TEST s5, 00000001'b ;set flags
RETURN
;
;
;------------------------------------------------------------------------------------------
; Subroutines used by the main I2C routines above
;------------------------------------------------------------------------------------------
;
; These routines actually control the I2C signals an ensure that timing specifications
; consistent with maximum bit rate of 100KHz are not exceeded.
;
;
; Drive CLK Low and wait for 5us before doing anything else.
;
I2C_clk_Low: AND sF, ~I2C_clk ;CLK = 0
OUTPUT sF, I2C_output_port
CALL I2C_delay_5us
RETURN
;
;
; Place CLK into tri-state (Z) so that it can go High.
; Then wait for CLK to actually become High before returning because a slave
; has the ability to stretch a clock to slow communication down.
;
I2C_clk_Z: OR sF, I2C_clk ;CLK = Z
OUTPUT sF, I2C_output_port
I2C_wait_clk_High: INPUT s0, I2C_input_port ;read external signals
TEST s0, I2C_clk ;test CLK bit
JUMP Z, I2C_wait_clk_High ;wait if CLK held Low by slave
RETURN
;
;
; Drive DATA Low and wait for 5us before doing anything else.
;
I2C_data_Low: AND sF, ~I2C_data ;DATA = 0
OUTPUT sF, I2C_output_port
RETURN
;
;
; Place DATA into tri-state (Z) so that it can go High.
; This can be used to transmit or receive a '1' but can also be used by the
; slave to return a '0' by holding the data line Low against the pull-up resistor.
;
I2C_data_Z: OR sF, I2C_data ;DATA = Z
OUTPUT sF, I2C_output_port
RETURN
;
;
; Receive one bit of data
;
; The bit received is shifted into the LSB of register 's5'.
;
; This the routine must be executed from the condition CLK low.
;
; The DATA line is released to allow a slave to transmit. There will be a
; 5us delay before the CLK is released to start a clock pulse. The start of
; the clock pulse can be delayed by a slave but a High duration of 4us is
; guaranteed. The value of the DATA line is sampled at the mid-point of the
; 4us high period (i.e. after 2us). The CLK clock pulse is followed by a
; delay of 5us before anything else can happen.
;
I2C_Rx_bit: CALL I2C_data_Z ;DATA = Z (slave can now drive)
CALL I2C_delay_5us
CALL I2C_clk_Z ;CLK = Z (waits until definitely High)
CALL I2C_delay_2us ;middle of SCL clock pulse
INPUT s0, I2C_input_port ;read external signals
TEST s0, I2C_data ;set carry flag with value of DATA
SLA s5 ;shift received bit into LSB of s5
CALL I2C_delay_2us ;complete 4us SCL clock pulse
CALL I2C_clk_Low ;end of clock pulse includes 5us delay
RETURN
;
;
; Software Delays for I2C Signal Timing
;
I2C_delay_5us: CALL I2C_delay_1us
I2C_delay_4us: CALL I2C_delay_1us
CALL I2C_delay_1us
I2C_delay_2us: CALL I2C_delay_1us
CALL I2C_delay_1us
RETURN
;
; The base delay is 1us and takes ((4 x I2C_time_reference) + 6) clock cycles
; to execute including the CALL instruction required to invoke it.
;
; For example, if the clock frequency is 100MHz then 'I2C_time_reference' should be set
; to 24'd. This will result in 24 iterations of the 'SUB' and 'JUMP NZ' loop resulting
; in the execution of 48 instructions. The invoking 'CALL', the 'LOAD' and the 'RETURN'
; bringing the total number of instructions to 51. All instructions take 2 clock cycles
; to execute so that is a total of 102 clock cycles which take 1.02us at 100MHz.
; i.e. ((4 x I2C_time_reference) + 6) = ((4 x 24) + 6) = 102 clock cycles
;
I2C_delay_1us: LOAD s0, I2C_time_reference
I2C_delay_loop: SUB s0, 1'd
JUMP NZ, I2C_delay_loop
RETURN
;
;
;------------------------------------------------------------------------------------------
; End of 'i2c_routines.psm'
;------------------------------------------------------------------------------------------
;

View File

@ -0,0 +1,527 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2011-2014, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; PicoBlaze Reference Design.
;
;
; Routines to communicate with some devices connected to the General Purpose I2C
; Communication bus on the Xilinx KC705 Evaluation Kit.
;
; The primary objective of the routines provided in this file are to communicate with
; the Si570 Programmable Oscillator, the Si5324 precision clock multiplier and the M24C08
; EEPROM. However, all these devices are accessed via an 8-channel I2C Switch (PCA9548)
; so routines are also provided to facilitate control of this switch.
;
; Support for other devices connected to the I2C switch may be provided in future versions
; of this file. However, it may also be worth considering the removal of routines
; associated with devices that are not required by your application especially if PicoBlaze
; code size needs to be reduced.
;
;
; Ken Chapman - Xilinx Ltd
;
; 24th April 2012 - Initial version (routines for PCA9548 and Si570)
; 11th October 2012 - Additional routines to support M24C08
; 25th October 2012 - Additional routines to support Si5324 and enhanced descriptions
; 19th August 2014 - Change to a comments only
;
;
;
; NOTE - This is not a standalone PSM file. Include this file in a program that
; then calls these routines and works with the values in scratch pad memory.
;
; INCLUDE "kc705_i2c_devices.psm"
;
;
; IMPORTANT - The routines contained in 'i2c_routines.psm' are used by the routines
; in this file. Therefore, this file must also be available and included
; in your program using INCLUDE "i2c_routines.psm".
;
;
; INTRODUCTION
; ------------
;
; On the Xilinx KC705 Evaluation Kit, the general purpose I2C interface on the FPGA
; only connects directly to an 8-channel I2C Switch which is a PCA9548 device from
; Philips Semiconductors. Communication with the switch enables one (or more) of the
; channels to be selected. Once a channel has been selected, the switch effectively
; becomes transparent so that communication with the device attached to that channel
; can proceed as if it were directly connected to the FPGA. On the KC705 board the
; channels are assigned as follows....
;
; CH0 - Si570 Programmable Oscillator
; CH1 - FMC-HPC slot
; CH2 - FMC-HPC slot
; CH3 - M24C08 EEPROM
; CH4 - SFP connector
; CH5 - ADV7511 HDMI transmitter
; CH6 - DDR3 connector
; CH7 - SI5326 precision clock multiplier
;
; The PCA9548 channel selection byte uses 'one-hot' encoding. For example, to select
; 'CH3' then bit-3 will need to be set by writing the control value 00001000'b to
; the PCA9548 device using the 'PCA9548_mux_write' routine.
;
; This file contains routines to set and verify the selection of the I2C switch channels
; and to communicate with the Si570 Programmable Oscillator once it has been selected.
;
;
; Hence typical code using these routines will be as follows...
;
; LOAD sD, 00000001'b ;Select Si570 connected to CH0
; CALL PCA9548_mux_write
;
; LOAD sB, 7'd ;Read 'Register7' from Si570
; CALL Si570_read
; STORE sD, Si570_register7
;
; LOAD sB, 7'd ;Write new value to 'Register7' in Si570
; FETCH sD, Si570_register7
; CALL Si570_write
;
; Your code may also include checks that ensure that communication is working properly
; by testing the state of the flags after calling the routines provided. However, such
; error detection code is often restricted to code used during initial development unless
; it is used in a high reliability product with error mitigation schemes (i.e. detecting
; an error is one thing; deciding what to do if an error does occur is another!).
;
;
;------------------------------------------------------------------------------------------
; Hardware Constants
;------------------------------------------------------------------------------------------
;
; The CONSTANT directives below define the 7-Bit I2C addresses of the PCA9548, M24C08,
; Si570 and Si5324 devices fitted on the Xilinx KC705 Evaluation Kit. These may need to be
; adjusted before using these routines with different hardware.
;
CONSTANT I2C_mux_address, 74 ; PCA9548 (8-channel) I2C Bus Switch
CONSTANT M24C08_base_address, 54 ; M24C08 (8k-bit) EEPROM (base address '10101aa')
CONSTANT Si570_address, 5D ; Si570 Programmable Oscillator
CONSTANT Si5324_address, 68 ; Si5324 (or Si5326) Precision Clock Multiplier
;
;
;------------------------------------------------------------------------------------------
; Registers
;------------------------------------------------------------------------------------------
;
; The following registers within the currently active bank are used by these routines....
;
; s0, s1, s5, sD and sF
;
;
;------------------------------------------------------------------------------------------
; Routine to write to the 8-channel I2C Switch (PCA9548).
;------------------------------------------------------------------------------------------
;
; The PCA9548 contains only one 8-bit control register resulting in a very simple I2C write
; transaction. Each bit of the control register corresponds with the selection of a channel
; (when a bit is '1' the corresponding channel is selected).
;
; When calling this routine, the channel selection should be provided in register 'sD'.
; This value will be written to the control register in the PCA9548.
;
; If for some reason communication with the PCA9548 is unsuccessful then the CARRY flag
; will be set and this could be tested by your code and used to take appropriate actions.
;
PCA9548_mux_write: CALL I2C_initialise ;ensure bus state and initialise 'sF'
CALL I2C_start ;bus start (S)
;
LOAD s5, I2C_mux_address ;device address (7-bits)
SL0 s5 ;Write operation (LSB = 0)
CALL I2C_Tx_byte ;Transmit address with write
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
LOAD s5, sD ;control value to be written
CALL I2C_Tx_byte ;Transmit control byte
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
CALL I2C_stop ;bus stop (P)
RETURN ;with Carry flag reset
;
;
;------------------------------------------------------------------------------------------
; Routine to read from the 8-channel I2C Switch (PCA9548).
;------------------------------------------------------------------------------------------
;
; The PCA9548 contains only one 8-bit control register resulting in a very simple I2C read
; transaction. Each bit of the control register corresponds with the selection of a channel
; (when a bit is '1' the corresponding channel is selected).
;
; When calling this routine, the control register in the PCA9548 is read and its value
; returned in register 'sD'.
;
; If for some reason communication with the PCA9548 is unsuccessful then the CARRY flag
; will be set and this could be tested by your code and used to take appropriate actions.
;
PCA9548_mux_read: CALL I2C_initialise ;ensure bus state and initialise 'sF'
CALL I2C_start ;bus start (S)
;
LOAD s5, I2C_mux_address ;device address (7-bits)
SL1 s5 ;Read operation (LSB = 1)
CALL I2C_Tx_byte ;Transmit address with write
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
CALL I2C_Rx_byte ;Read control value
LOAD sD, s5
;
CALL I2C_Tx_NACK ;Transmit NACK to end read operation
CALL I2C_stop ;transmit stop (P)
RETURN ;with Carry flag reset
;
;
;------------------------------------------------------------------------------------------
; Routine to write to the M24C08 EEPROM
;------------------------------------------------------------------------------------------
;
; The M24C08 is an 8k-bit EEPROM memory. Internally to the M24C08 the memory is organised
; as 1024 bytes of randomly accessible non-volatile memory. This results in an 10-bit
; memory address. Any byte can be randomly accessed for read or write.
;
; This routine will write the byte supplied in register 'sD' to the address specified by
; the [s8,s7] registers. Following the write transaction a delay of 20ms is invoked to
; cover the worst case write time (tW) indicated in the M24C08 data sheet.
;
; NOTE - [s8,s7] must be an address in the range 000 to 3FF hex.
;
; If for some reason communication with the M24C08 is unsuccessful then the CARRY flag will
; be set and this could be tested by your code and used to take appropriate actions.
;
; HINT - On the Xilinx KC705 Evaluation Board you must select 'CH3' on the I2C switch
; before this routine is used.
;
; WARNING - Be careful not waste the 1 million write cycles! EEPROM is an excellent
; way to preserve a limited amount of valuable information but be careful how
; often it is updated. For example, if you were to perform one write to the
; EEPROM every second then the 1 million writes would be achieved under 12 days.
;
; HINT - The number of write cycles used can be reduced by performing 'page
; writes' of up to 16 adjacent locations in a single IIC transaction so not
; such 'random access' and requires further consideration to be used correctly!
;
; The 10-bit address required to specify the memory location within the EEPROM is divided
; into two sections.
;
; address[9:8] - These two bits replace the least significant 2 bits of the 7-bit
; M24C08 device identifier before KCPSM6 accesses the device.
;
; address[7:0] - These 8-bits are are transmitted after the modified device
; identifier in the traditional way.
;
; For example
;
; EEPROM address = 2C7 = 1011000111 which is split into 10 and 11000111.
; The 7-bit device base address of the M24C08 is 74 = 1010100
; The lower 2 bits of the device base address are replaced with the
; upper 2 bits of the EEPROM address
; 10101xx
; 10 Modified 7-bit device address = 1010110
; Then as normal for I2C transactions a read/write bit is appended to the
; Modified 7-bit device address before transmission to the device.
;
;
M24C08_write: CALL I2C_initialise ;ensure bus state and initialise 'sF'
CALL I2C_start ;bus start (S)
;
LOAD s5, M24C08_base_address ;device base address (7-bits)
OR s5, s8 ;merge with EEPROM address[9:8]
SL0 s5 ;Write operation (LSB = 0)
CALL I2C_Tx_byte ;Transmit address with write
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
LOAD s5, s7 ;EEPROM address[7:0]
CALL I2C_Tx_byte
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
LOAD s5, sD ;Data to be written to M24C08 memory
CALL I2C_Tx_byte
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
CALL I2C_stop ;transmit stop (P)
CALL delay_20ms ;time for M24C08 write to complete
AND s0, FF ;clear carry flag (write successful)
RETURN ;with Carry flag reset
;
;
;------------------------------------------------------------------------------------------
; Routine to read from the M24C08 EEPROM
;------------------------------------------------------------------------------------------
;
; The M24C08 is an 8k-bit EEPROM memory. Internally to the M24C08 the memory is organised
; as 1024 bytes of randomly accessible non-volatile memory. This results in an 10-bit
; memory address. Any byte can be randomly accessed for read or write.
;
; This routine will read the byte from the M24C08 address specified by the [s8,s7]
; registers and return it in register 'sD'.
;
; NOTE - [s8,s7] must be an address in the range 000 to 3FF hex.
;
; If for some reason communication with the M24C08 is unsuccessful then the CARRY flag will
; be set and this could be tested by your code and used to take appropriate actions.
;
; HINT - On the Xilinx KC705 Evaluation Board you must select 'CH3' on the I2C switch
; before this routine is used.
;
; HINT - It is possible to continuously read data stored sequentially in the M24C08 EEPROM
; which improves performance (reduced overhead associated with the start of
; separate read transactions). Obviously a scheme needs to be put in place to
; handle the flow of data is this facility is used.
;
M24C08_read: CALL I2C_initialise ;ensure bus state and initialise 'sF'
CALL I2C_start ;bus start (S)
;
LOAD s5, M24C08_base_address ;device base address (7-bits)
OR s5, s8 ;merge with EEPROM address[9:8]
SL0 s5 ;Write operation (LSB = 0)
CALL I2C_Tx_byte ;Transmit address with write
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
LOAD s5, s7 ;EEPROM address[7:0]
CALL I2C_Tx_byte
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
CALL I2C_start ;bus restart (Sr)
;
LOAD s5, M24C08_base_address ;device base address (7-bits)
OR s5, s8 ;merge with EEPROM address[9:8]
SL1 s5 ;Read operation (LSB = 1)
CALL I2C_Tx_byte ;Transmit address with write
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
CALL I2C_Rx_byte ;Read data from M24C08
LOAD sD, s5
;
CALL I2C_Tx_NACK ;Transmit NACK to end read operation
CALL I2C_stop ;transmit stop (P)
RETURN ;with Carry flag reset
;
;
;------------------------------------------------------------------------------------------
; Routine to write to the Si570 Programmable Oscillator
;------------------------------------------------------------------------------------------
;
; The Si570 contains 14 'Serial Port Registers' each of which is 8-bits and described in
; the data sheet from Silicon Labs. The I2C transaction to write a value to a register
; first identifies the target register and then provides the value to be written to it.
;
; When calling this routine, register 'sB' must specify the Si570 register to be written
; and register 'sD' must provide the value to be written.
;
; If for some reason communication with the Si570 is unsuccessful then the CARRY flag will
; be set and this could be tested by your code and used to take appropriate actions.
;
; HINT - On the Xilinx KC705 Evaluation Board you must select 'CH0' on the I2C switch
; before this routine is used.
;
Si570_write: CALL I2C_initialise ;ensure bus state and initialise 'sF'
CALL I2C_start ;bus start (S)
;
LOAD s5, Si570_address ;device address (7-bits)
SL0 s5 ;Write operation (LSB = 0)
CALL I2C_Tx_byte ;Transmit address with write
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
LOAD s5, sB ;Select Si570 register
CALL I2C_Tx_byte
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
LOAD s5, sD ;Write to Si570 register
CALL I2C_Tx_byte
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
CALL I2C_stop ;transmit stop (P)
RETURN ;with Carry flag reset
;
;
;------------------------------------------------------------------------------------------
; Routine to read from the Si570 Programmable Oscillator
;------------------------------------------------------------------------------------------
;
; The Si570 contains 14 'Serial Port Registers' each of which is 8-bits and described in
; the data sheet from Silicon Labs. The I2C transaction to read a value from a register
; first identifies the target register and then reads the value from it.
;
; When calling this routine, register 'sB' must specify the Si570 register to be read
; and the value read from that Si570 register will be returned in register 'sD'.
;
; If for some reason communication with the Si570 is unsuccessful then the CARRY flag will
; be set and this could be tested by your code and used to take appropriate actions.
;
; HINT - On the Xilinx KC705 Evaluation Board you must select 'CH0' on the I2C switch
; before this routine is used.
;
Si570_read: CALL I2C_initialise ;ensure bus state and initialise 'sF'
CALL I2C_start ;bus start (S)
;
LOAD s5, Si570_address ;device address (7-bits)
SL0 s5 ;Write operation (LSB = 0)
CALL I2C_Tx_byte ;Transmit address with write
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
LOAD s5, sB ;Select Si570 register
CALL I2C_Tx_byte
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
CALL I2C_start ;bus restart (Sr)
;
LOAD s5, Si570_address ;device address (7-bits)
SL1 s5 ;Read operation (LSB = 1)
CALL I2C_Tx_byte ;Transmit address with write
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
CALL I2C_Rx_byte ;Read Si570 register value
LOAD sD, s5
;
CALL I2C_Tx_NACK ;Transmit NACK to end read operation
CALL I2C_stop ;transmit stop (P)
RETURN ;with Carry flag reset
;
;
;------------------------------------------------------------------------------------------
; Routine to write to the Si5324 (or Si5326) Precision Clock Multiplier
;------------------------------------------------------------------------------------------
;
; The Si5324 contains 49 'Serial Port Registers' each of which is 8-bits and described in
; the data sheet from Silicon Labs. The I2C transaction to write a value to a register
; first identifies the target register and then provides the value to be written to it.
;
; When calling this routine, register 'sB' must specify the Si5324 register to be written
; and register 'sD' must provide the value to be written.
;
; If for some reason communication with the Si5324 is unsuccessful then the CARRY flag will
; be set and this could be tested by your code and used to take appropriate actions.
;
; HINT - On the Xilinx KC705 Evaluation Board you must select 'CH7' on the I2C switch
; before this routine is used.
;
Si5324_write: CALL I2C_initialise ;ensure bus state and initialise 'sF'
CALL I2C_start ;bus start (S)
;
LOAD s5, Si5324_address ;device address (7-bits)
SL0 s5 ;Write operation (LSB = 0)
CALL I2C_Tx_byte ;Transmit address with write
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
LOAD s5, sB ;Select Si5324 register
CALL I2C_Tx_byte
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
LOAD s5, sD ;Write to Si5324 register
CALL I2C_Tx_byte
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
CALL I2C_stop ;transmit stop (P)
RETURN ;with Carry flag reset
;
;
;------------------------------------------------------------------------------------------
; Routine to read from the Si5324 (or Si5326) Precision Clock Multiplier
;------------------------------------------------------------------------------------------
;
; The Si5324 contains 49 'Serial Port Registers' each of which is 8-bits and described in
; the data sheet from Silicon Labs. The I2C transaction to read a value from a register
; first identifies the target register and then reads the value from it.
;
; When calling this routine, register 'sB' must specify the Si5324 register to be read
; and the value read from that Si570 register will be returned in register 'sD'.
;
; If for some reason communication with the Si5324 is unsuccessful then the CARRY flag will
; be set and this could be tested by your code and used to take appropriate actions.
;
; HINT - On the Xilinx KC705 Evaluation Board you must select 'CH7' on the I2C switch
; before this routine is used.
;
Si5324_read: CALL I2C_initialise ;ensure bus state and initialise 'sF'
CALL I2C_start ;bus start (S)
;
LOAD s5, Si5324_address ;device address (7-bits)
SL0 s5 ;Write operation (LSB = 0)
CALL I2C_Tx_byte ;Transmit address with write
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
LOAD s5, sB ;Select Si5324 register
CALL I2C_Tx_byte
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
CALL I2C_start ;bus restart (Sr)
;
LOAD s5, Si5324_address ;device address (7-bits)
SL1 s5 ;Read operation (LSB = 1)
CALL I2C_Tx_byte ;Transmit address with write
CALL I2C_Rx_ACK ;Receive ACK
RETURN C ;Return on failure (Carry flag set)
;
CALL I2C_Rx_byte ;Read Si5324 register value
LOAD sD, s5
;
CALL I2C_Tx_NACK ;Transmit NACK to end read operation
CALL I2C_stop ;transmit stop (P)
RETURN ;with Carry flag reset
;
;
;------------------------------------------------------------------------------------------
; End of 'kc705_i2c_devices.psm'
;------------------------------------------------------------------------------------------
;

View File

@ -0,0 +1,118 @@
#
#------------------------------------------------------------------------------------------
# Copyright <20> 2012-2013, Xilinx, Inc.
# This file contains confidential and proprietary information of Xilinx, Inc. and is
# protected under U.S. and international copyright and other intellectual property laws.
#------------------------------------------------------------------------------------------
#
# Disclaimer:
# This disclaimer is not a license and does not grant any rights to the materials
# distributed herewith. Except as otherwise provided in a valid license issued to
# you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
# MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
# DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
# INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
# OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
# (whether in contract or tort, including negligence, or under any other theory
# of liability) for any loss or damage of any kind or nature related to, arising
# under or in connection with these materials, including for any direct, or any
# indirect, special, incidental, or consequential loss or damage (including loss
# of data, profits, goodwill, or any type of loss or damage suffered as a result
# of any action brought by a third party) even if such damage or loss was
# reasonably foreseeable or Xilinx had been advised of the possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-safe, or for use in any
# application requiring fail-safe performance, such as life-support or safety
# devices or systems, Class III medical devices, nuclear facilities, applications
# related to the deployment of airbags, or any other applications that could lead
# to death, personal injury, or severe property or environmental damage
# (individually and collectively, "Critical Applications"). Customer assumes the
# sole risk and liability of any use of Xilinx products in Critical Applications,
# subject only to applicable laws and regulations governing limitations on product
# liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
#
#------------------------------------------------------------------------------------------
#
# Constraints for 'kc705_kcpsm6_i2c_eeprom'.
#
# KC705 Board Rev.D (www.xilinx.com)
#
# XC7K325T-1FFG900 Device
#
# Ken Chapman - Xilinx Ltd
#
# 11th October 2012 - Initial Release.
# 28th January 2013 - Addition of pin connected to Si5324 (U70) reset control.
#
#
#
#------------------------------------------------------------------------------------------
# Timing Constraints
#------------------------------------------------------------------------------------------
#
#
# Period constraint for 200MHz operation
#
NET "clk200" TNM_NET = "clk200";
TIMESPEC TS_200MHZ_clk = PERIOD "clk200" 5.0ns HIGH 50%;
#
#
# Period constraint for 100MHz operation
#
NET "clk" TNM_NET = "clk";
TIMESPEC TS_100MHZ_clk = PERIOD "clk" 10.0ns HIGH 50%;
#
#
#------------------------------------------------------------------------------------------
# Pin Constraints
#------------------------------------------------------------------------------------------
#
#
# 200MHz Differential Clock (SYSCLK).
#
NET "clk200_p" LOC = "AD12" | IOSTANDARD = DIFF_SSTL15;
NET "clk200_n" LOC = "AD11" | IOSTANDARD = DIFF_SSTL15;
#
#
# USB-UART
#
NET "uart_rx" LOC = "M19" | IOSTANDARD = LVCMOS25;
NET "uart_tx" LOC = "K24" | IOSTANDARD = LVCMOS25 | SLEW = SLOW | DRIVE = 4;
#
#
# CPU_RST press switch is SW7 and active High
#
NET "cpu_rst" LOC = "AB7" | IOSTANDARD = LVCMOS15;
#
#
# I2C Bus
#
# The Kintex-7 connects to an I2C bus switch (PCA9548).
#
# The PCA9548 address is "1110100" (74 hex).
# The M24C08 EEPROM is connected to 'CH3' and has address "10101xx"
# ('xx' signify memory address bits so I2C address range is 54 to 57 hex).
#
# All signals have 4k7 external pull-up resistors.
#
NET "i2c_clk" LOC = "K21" | IOSTANDARD = LVCMOS25 | SLEW = SLOW | DRIVE = 4;
NET "i2c_data" LOC = "L21" | IOSTANDARD = LVCMOS25 | SLEW = SLOW | DRIVE = 4;
NET "i2c_mux_reset_b" LOC = "P23" | IOSTANDARD = LVCMOS25 | SLEW = SLOW | DRIVE = 4;
#
#
# Si5324 (U70) reset active Low
#
# This pin must be driven High in order to communicate with the Si5324 device.
# Although not used in this reference design, this connection is made to facilitate
# future development and experiments with I2C.
#
NET "si5324_rst" LOC = "AE20" | IOSTANDARD = LVCMOS25;
#
#
#------------------------------------------------------------------------------------------
# End of File
#------------------------------------------------------------------------------------------
#

View File

@ -0,0 +1,640 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2011-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
-- <20> _<> ______ ____<5F> ____<5F> __<5F> __<5F> __<5F><5F>
-- | |/ / ___|<7C> _ \/ ___||<7C> \/<2F> |/ /_<>
-- | ' / |<7C><> | |_) \___ \| |\/| | '_ \
-- | . \ |___|<7C> __/ ___) | |<7C> | | (_) )
-- |_|\_\____|_|<7C><> |____/|_|<7C> |_|\___/
-- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
--
--
-- KCPSM6 reference design on Xilinx KC705 Evaluation Board (www.xilinx.com).
--
-- XC7K325T-1FFG900 Device
--
-- Ken Chapman - Xilinx Ltd.
--
-- 11th October 2012 - Initial version.
-- 28th January 2013 - Addition of pin connected to Si5324 (U70) reset control.
-- 18th March 2013 - Alterations to names of modules.
--
--
-- The primary purpose of this reference design is to illustrate how KCPSM6 can implement
-- the signaling and protocol required to communicate and control an I2C bus and devices.
--
-- The design is based on the standard reference designs provided with KCPSM6 (PicoBlaze).
-- These provide a UART-USB connection allowing messages to be displayed on a terminal and
-- for keyboard entries to allow a degree of control and data input. Please refer to the
-- documentation provided with KCPSM6 and the UART macros if you need to know more about
-- PicoBlaze and UART communication. PicoTerm is also supplied with KCPSM6 and ideally
-- suited to this application so please use it.
--
-- In this example the aim is to communicate with the M24C08 EEPROM device on the KC705
-- board. In order to achieve this, it is also necessary to control the PCA9548 I2C Bus
-- Switch. So in this case, KCPSM6 and the Kintex-7 device will be the I2C Bus 'Master'
-- and the PCA9548 and M24C08 devices will be I2C Bus 'Slaves'.
--
-- Whilst this is a simple design example meeting the specific requirements of these
-- devices on the KC705 board it is hoped that this design can be a reference starting
-- point for other arrangements. The design implements a classic I2C interface and serial
-- communication. Most of the work is performed by KCPSM6 which is defined and described in
-- the PSM code provided. However, the starting point is to set up the two bi-directional
-- signals.
--
-- The I2C interface is formed of two signals...
--
-- i2c_clk Clock Pin K21
-- i2c_data Data Pin L21
--
-- Both pins are effectively 'open collector'. This means that the KCPSM6 in this Kintex-7
-- design only has the ability to force the signals Low. High levels can only be achieved
-- by the external pull-up resistors when no device (master or slaves) are driving Low.
-- If you are unfamiliar with the implementation of bi-directional 'open collector' pins
-- in VHDL then do take time to review the definition because its nature causes it to be
-- somewhat distributed within this file!
--
-- Hint - When KCPSM6 reads the I2C bus signals it is vital that it observes the states
-- of the signals on the physical pins of the Kintex-7 device. It is all too easy
-- to make the mistake of reading the internal signals (which define the output
-- states of the pins) especially if the KCPSM6 master is placed in a lower level
-- of hierarchy.
--
-- Please be aware that this design also has the ability to control the hardware reset
-- to the PCA9548 device. This signal is specific to the PCA9548 device and outside the
-- normal scope of I2C. It is common practice for this signal not to be connected and
-- controlled (an external pull-up will hold it High and inactive). However, control of
-- this signal has been included in this reference design due to the way in which the
-- KC705 is typically used to conduct experiments. For example, the Kintex-7 device is
-- likely to be reconfigured during design development without cycling the power to the
-- board. For this reason there is a possibility that an I2C transaction will be truncated
-- in such a way that the I2C bus and slave devices are left in a confused state. In this
-- reference design, KCPSM6 will generate a reset pulse to the PCA9548 as part of the
-- initialisation phase to help recover from any bus fault conditions that may be present.
--
--
-------------------------------------------------------------------------------------------
--
-- Library declarations
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
--
-------------------------------------------------------------------------------------------
--
--
entity kc705_kcpsm6_i2c_eeprom is
Port ( uart_rx : in std_logic;
uart_tx : out std_logic;
i2c_clk : inout std_logic;
i2c_data : inout std_logic;
i2c_mux_reset_b : out std_logic := '1';
cpu_rst : in std_logic;
si5324_rst : out std_logic;
clk200_p : in std_logic;
clk200_n : in std_logic);
end kc705_kcpsm6_i2c_eeprom;
--
-------------------------------------------------------------------------------------------
--
-- Start of test architecture
--
architecture Behavioral of kc705_kcpsm6_i2c_eeprom is
--
-------------------------------------------------------------------------------------------
--
-- Components
--
-------------------------------------------------------------------------------------------
--
--
-- declaration of KCPSM6
--
component kcpsm6
generic( hwbuild : std_logic_vector(7 downto 0) := X"00";
interrupt_vector : std_logic_vector(11 downto 0) := X"3FF";
scratch_pad_memory_size : integer := 64);
port ( address : out std_logic_vector(11 downto 0);
instruction : in std_logic_vector(17 downto 0);
bram_enable : out std_logic;
in_port : in std_logic_vector(7 downto 0);
out_port : out std_logic_vector(7 downto 0);
port_id : out std_logic_vector(7 downto 0);
write_strobe : out std_logic;
k_write_strobe : out std_logic;
read_strobe : out std_logic;
interrupt : in std_logic;
interrupt_ack : out std_logic;
sleep : in std_logic;
reset : in std_logic;
clk : in std_logic);
end component;
--
-- Development Program Memory
--
component m24c08_i2c_uart_bridge
generic( C_FAMILY : string := "S6";
C_RAM_SIZE_KWORDS : integer := 1;
C_JTAG_LOADER_ENABLE : integer := 0);
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
rdl : out std_logic;
clk : in std_logic);
end component;
--
-- UART Transmitter with integral 16 byte FIFO buffer
--
component uart_tx6
Port ( data_in : in std_logic_vector(7 downto 0);
en_16_x_baud : in std_logic;
serial_out : out std_logic;
buffer_write : in std_logic;
buffer_data_present : out std_logic;
buffer_half_full : out std_logic;
buffer_full : out std_logic;
buffer_reset : in std_logic;
clk : in std_logic);
end component;
--
-- UART Receiver with integral 16 byte FIFO buffer
--
component uart_rx6
Port ( serial_in : in std_logic;
en_16_x_baud : in std_logic;
data_out : out std_logic_vector(7 downto 0);
buffer_read : in std_logic;
buffer_data_present : out std_logic;
buffer_half_full : out std_logic;
buffer_full : out std_logic;
buffer_reset : in std_logic;
clk : in std_logic);
end component;
--
--
-------------------------------------------------------------------------------------------
--
-- Signals
--
-------------------------------------------------------------------------------------------
--
--
--
-- Signals to create and distribute a 100MHz clock from the 200MHz differential input
--
signal clock_divide : std_logic := '0';
signal clk200 : std_logic;
signal clk : std_logic;
--
--
-- Signals used to connect KCPSM6
--
signal address : std_logic_vector(11 downto 0);
signal instruction : std_logic_vector(17 downto 0);
signal bram_enable : std_logic;
signal in_port : std_logic_vector(7 downto 0);
signal out_port : std_logic_vector(7 downto 0);
signal port_id : std_logic_vector(7 downto 0);
signal write_strobe : std_logic;
signal k_write_strobe : std_logic;
signal read_strobe : std_logic;
signal interrupt : std_logic;
signal interrupt_ack : std_logic;
signal kcpsm6_sleep : std_logic;
signal kcpsm6_reset : std_logic;
signal rdl : std_logic;
--
-- Signals used to connect UART_TX6
--
signal uart_tx_data_in : std_logic_vector(7 downto 0);
signal write_to_uart_tx : std_logic;
signal uart_tx_data_present : std_logic;
signal uart_tx_half_full : std_logic;
signal uart_tx_full : std_logic;
signal uart_tx_reset : std_logic;
--
-- Signals used to connect UART_RX6
--
signal uart_rx_data_out : std_logic_vector(7 downto 0);
signal read_from_uart_rx : std_logic;
signal uart_rx_data_present : std_logic;
signal uart_rx_half_full : std_logic;
signal uart_rx_full : std_logic;
signal uart_rx_reset : std_logic;
--
-- Signals used to define baud rate
--
signal baud_count : integer range 0 to 53 := 0;
signal en_16_x_baud : std_logic := '0';
--
--
-- Signals for IIC Bus
--
-- Internal signals are required to implement bi-directional pins.
--
--
signal drive_i2c_clk : std_logic;
signal drive_i2c_data : std_logic;
--
--
-------------------------------------------------------------------------------------------
--
-- Start of circuit description
--
-------------------------------------------------------------------------------------------
--
begin
--
-----------------------------------------------------------------------------------------
-- Create 100MHz clock from 200MHz differential input
-----------------------------------------------------------------------------------------
--
-- A simple toggle flip-flop arrangement is used to divide the clock and no phase
-- relationship with the original 200MHz clock is required in this application.
--
--
-- 200MHz differential input clock
--
clk200_input_buffer: IBUFGDS
port map ( I => clk200_p,
IB => clk200_n,
O => clk200);
clock_generation: process(clk200)
begin
if clk200'event and clk200 = '1' then
clock_divide <= not(clock_divide);
end if;
end process clock_generation;
--
-- BUFG to distribute 100MHz clock
--
clock_100mhz_buffer: BUFG
port map ( I => clock_divide,
O => clk);
--
-----------------------------------------------------------------------------------------
-- Instantiate KCPSM6 and connect to program ROM
-----------------------------------------------------------------------------------------
--
-- The generics can be defined as required. In this case the 'hwbuild' value is used to
-- define a version using the ASCII code for the desired letter and the interrupt vector
-- has been set to 7F0 to provide 16 instructions for an Interrupt Service Routine (ISR)
-- before reaching the end of a 2K memory.
--
--
processor: kcpsm6
generic map ( hwbuild => X"42", -- 42 hex is ASCII character "B"
interrupt_vector => X"7F0",
scratch_pad_memory_size => 256)
port map( address => address,
instruction => instruction,
bram_enable => bram_enable,
port_id => port_id,
write_strobe => write_strobe,
k_write_strobe => k_write_strobe,
out_port => out_port,
read_strobe => read_strobe,
in_port => in_port,
interrupt => interrupt,
interrupt_ack => interrupt_ack,
sleep => kcpsm6_sleep,
reset => kcpsm6_reset,
clk => clk);
--
-- Reset by press button (active Low) or JTAG Loader enabled Program Memory
--
kcpsm6_reset <= rdl or cpu_rst;
--
-- Unused signals tied off until required.
-- Tying to other signals used to minimise warning messages.
--
kcpsm6_sleep <= write_strobe and k_write_strobe; -- Always '0'
interrupt <= interrupt_ack;
--
-- Development Program Memory
-- JTAG Loader enabled for rapid code development.
--
program_rom: m24c08_i2c_uart_bridge
generic map( C_FAMILY => "7S",
C_RAM_SIZE_KWORDS => 2,
C_JTAG_LOADER_ENABLE => 1)
port map( address => address,
instruction => instruction,
enable => bram_enable,
rdl => rdl,
clk => clk);
--
-----------------------------------------------------------------------------------------
-- I2C Bus Interface
-----------------------------------------------------------------------------------------
--
-- 'i2c_clk' and 'i2c_data' are open collector bidirectional pins.
--
-- When KCPSM6 presents a '0' to either of the 'drive' signals the corresponding pin
-- will be forced Low.
--
-- When KCPSM6 presents a '1' to either of the 'drive' signals the corresponding pin
-- will become high impedance ('Z') allowing the signal to be pulled High by the
-- external pull-up or driven Low by a Slave device.
--
i2c_clk <= '0' when drive_i2c_clk = '0' else 'Z';
i2c_data <= '0' when drive_i2c_data = '0' else 'Z';
--
-----------------------------------------------------------------------------------------
-- UART Transmitter with integral 16 byte FIFO buffer
-----------------------------------------------------------------------------------------
--
-- Write to buffer in UART Transmitter at port address 01 hex
--
tx: uart_tx6
port map ( data_in => uart_tx_data_in,
en_16_x_baud => en_16_x_baud,
serial_out => uart_tx,
buffer_write => write_to_uart_tx,
buffer_data_present => uart_tx_data_present,
buffer_half_full => uart_tx_half_full,
buffer_full => uart_tx_full,
buffer_reset => uart_tx_reset,
clk => clk);
--
-----------------------------------------------------------------------------------------
-- UART Receiver with integral 16 byte FIFO buffer
-----------------------------------------------------------------------------------------
--
-- Read from buffer in UART Receiver at port address 01 hex.
--
-- When KCPMS6 reads data from the receiver a pulse must be generated so that the
-- FIFO buffer presents the next character to be read and updates the buffer flags.
--
rx: uart_rx6
port map ( serial_in => uart_rx,
en_16_x_baud => en_16_x_baud,
data_out => uart_rx_data_out,
buffer_read => read_from_uart_rx,
buffer_data_present => uart_rx_data_present,
buffer_half_full => uart_rx_half_full,
buffer_full => uart_rx_full,
buffer_reset => uart_rx_reset,
clk => clk);
--
-----------------------------------------------------------------------------------------
-- RS232 (UART) baud rate
-----------------------------------------------------------------------------------------
--
-- To set serial communication baud rate to 115,200 then en_16_x_baud must pulse
-- High at 1,843,200Hz which is every 54.28 cycles at 100MHz. In this implementation
-- a pulse is generated every 54 cycles resulting is a baud rate of 115,741 baud which
-- is only 0.5% high and well within limits.
--
baud_rate: process(clk)
begin
if clk'event and clk = '1' then
if baud_count = 53 then -- counts 54 states including zero
baud_count <= 0;
en_16_x_baud <= '1'; -- single cycle enable pulse
else
baud_count <= baud_count + 1;
en_16_x_baud <= '0';
end if;
end if;
end process baud_rate;
--
-----------------------------------------------------------------------------------------
-- General Purpose Input Ports.
-----------------------------------------------------------------------------------------
--
-- Two input ports are used with the UART macros. The first is used to monitor the flags
-- on both the UART transmitter and receiver. The second is used to read the data from
-- the UART receiver. Note that the read also requires a 'buffer_read' pulse to be
-- generated.
--
-- This design includes a third input port to read 8 general purpose switches.
--
input_ports: process(clk)
begin
if clk'event and clk = '1' then
case port_id(1 downto 0) is
-- Read UART status at port address 00 hex
when "00" => in_port(0) <= uart_tx_data_present;
in_port(1) <= uart_tx_half_full;
in_port(2) <= uart_tx_full;
in_port(3) <= uart_rx_data_present;
in_port(4) <= uart_rx_half_full;
in_port(5) <= uart_rx_full;
-- Read UART_RX6 data at port address 01 hex
-- (see 'buffer_read' pulse generation below)
when "01" => in_port <= uart_rx_data_out;
-- Read I2C Bus at port address 02 hex
when "10" => in_port(0) <= i2c_clk;
in_port(1) <= i2c_data;
-- Unused port address 03 hex
-- when "11" => in_port <= ????;
-- Don't Care for unsued case(s) ensures minimum logic implementation
when others => in_port <= "XXXXXXXX";
end case;
-- Generate 'buffer_read' pulse following read from port address 01
if (read_strobe = '1') and (port_id(1 downto 0) = "01") then
read_from_uart_rx <= '1';
else
read_from_uart_rx <= '0';
end if;
end if;
end process input_ports;
--
-----------------------------------------------------------------------------------------
-- General Purpose Output Ports
-----------------------------------------------------------------------------------------
--
-- In this design there are two output ports.
-- A simple output port used to control the I2C bus pins.
-- A port used to write data directly to the FIFO buffer within 'uart_tx6' macro.
--
output_ports: process(clk)
begin
if clk'event and clk = '1' then
-- 'write_strobe' is used to qualify all writes to general output ports.
if write_strobe = '1' then
-- Write to I2C Bus at port port address 08 hex
if port_id(3) = '1' then
drive_i2c_clk <= out_port(0);
drive_i2c_data <= out_port(1);
end if;
end if;
end if;
end process output_ports;
--
-- Write directly to the FIFO buffer within 'uart_tx6' macro at port address 01 hex.
-- Note the direct connection of 'out_port' to the UART transmitter macro and the
-- way that a single clock cycle write pulse is generated to capture the data.
--
uart_tx_data_in <= out_port;
write_to_uart_tx <= '1' when (write_strobe = '1') and (port_id(0) = '1')
else '0';
--
-----------------------------------------------------------------------------------------
-- Constant-Optimised Output Ports
-----------------------------------------------------------------------------------------
--
-- Two constant-optimised output ports are used to facilitate resetting of the UART
-- macros and to allow KCPSM6 to control the hardware rest to the PCA9548 device.
--
constant_output_ports: process(clk)
begin
if clk'event and clk = '1' then
if k_write_strobe = '1' then
-- Reset buffers in UART macros at constant port address 1 hex
if port_id(0) = '1' then
uart_tx_reset <= out_port(0);
uart_rx_reset <= out_port(1);
end if;
-- Reset I2C bus switch (PCA9548) at constant port address 2 hex
-- Note that the PCA9548 reset is active Low
if port_id(1) = '1' then
i2c_mux_reset_b <= out_port(0);
end if;
end if;
end if;
end process constant_output_ports;
--
-----------------------------------------------------------------------------------------
-- Reset Control on Si5324 Device
-----------------------------------------------------------------------------------------
--
-- Although the Si5324 (U70) device is not used in this reference design, it is a
-- device connected to the I2C bus (I2C multiplexer channel 7) and suitable for
-- further experiments. However, this device will not respond unless the reset control
-- is High so this assignment ensures that it is.
--
si5324_rst <= '1';
--
-----------------------------------------------------------------------------------------
--
end Behavioral;
-------------------------------------------------------------------------------------------
--
-- END OF FILE kc705_kcpsm6_i2c_eeprom.vhd
--
-------------------------------------------------------------------------------------------

View File

@ -0,0 +1,990 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2011-2013, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; KCPSM6 reference design: I2C Communication with M24C08 EEPROM device on the KC705 board
; which also requires control of a PCA9548 I2C Bus Switch.
;
;
;
; Ken Chapman - Xilinx Ltd
;
; 12th October 2012 - Initial version
; 18th March 2013 - Constant directives defining ASCII control characters removed
; (pre-defined in KCPSM6 assembler v2.43 or later).
;
;
;
; INTRODUCTION
;
; The primary purpose of this reference design is to illustrate how KCPSM6 can implement
; the signaling and protocol required to communicate and control an I2C bus and devices.
;
; The design is based on the standard reference designs provided with KCPSM6 (PicoBlaze).
; These provide a UART-USB connection allowing messages to be displayed on a terminal and
; for keyboard entries to allow a degree of control and data input. Please refer to the
; documentation provided with KCPSM6 and the UART macros if you need to know more about
; PicoBlaze and UART communication. PicoTerm is also supplied with KCPSM6 and ideally
; suited to this application so please use it.
;
; In this example, the aim is to communicate with the M24C08 EEPROM device on the KC705
; board. Due to the arrangement on the KC705 board this also requires the selection
; of 'CH3' on the PCA9548 I2C Bus Switch to which the EEPROM is connected. As such, this
; program is actually an example of communication with two I2C devices which hopefully
; makes it more realistic, interesting and educational. Please see 'kc705_i2c_devices.psm'
; for more details of the I2C arrangement and routines that communicate with these devices.
;
; The hardware defines a classic 2-wire I2C interface ready for serial communication.
;
; i2c_clk Clock
; i2c_data Data
;
; Both signals are bi-directional. One KCPSM6 output port is used to control the output
; drive ('open collector' style outputs can be driven Low or tri-stated). One KCPSM6
; input port is used to read the states of both signals. Absolutely everything related
; to the generation of I2C signals and the communication protocol is implemented by
; KCPSM6 and defined within the PSM files provided (detailed descriptions are provided
; in the PSM code).
;
; Please be aware that this program also generates a pulse to the hardware reset
; control on the PCA9548 device using one constant output port. This is not really part
; of the I2C signaling but can help to recover from any bus fault conditions that may
; occur when experimenting with the KC705 board.
;
; This program is only intended to provide a simple example of communication with the
; EEPROM device. The terminal (PicoTerm) provides a convenient way to interact with the
; design and a useful way to develop and verify EEPROM memory operations. In most real
; applications there is no compelling reason to retain the UART sections and certainly
; the I2C code has no dependence on the UART related code.
;
; The M24C08 is an 8k-bit EEPROM memory organised as 1024 bytes. This means that it
; has a 10-bit address (range 000 to 3FF hex). In this PSM file the 10-bit address
; handling is easily handled using a pair or registers. However. the way in which the
; 10-bit addresses are communicated to the M24C08 is less obvious. You might be
; interested to review the implementation and descriptions provided with the
; relevant routines contained in 'kc705_i2c_devices.psm' (or maybe you are just
; happy to accept that the low level details have already been covered for you).
;
;
; NOTE - This PSM file includes further PSM files so these must also be present
; when running the KCPSM6 assembler (v2.00 or later). It is hoped that the
; included files will also be suitable for reuse and inclusion in your own
; programs. For this reason each file contains descriptions of the routines
; that are provided.
;
; i2c_routines.psm - A set of routines to implement fundamental
; I2C signaling.
;
; kc705_i2c_devices.psm - A set of routines which implement I2C transactions
; with some of the devices on the KC705 board
; including the PCA9548 and M24C08 which are the
; focus of this design.
;
; PicoTerm_routines.psm - A set of routines to interface with the UART
; macros and use the PicoTerm features.
;
; soft_delays_100mhz.psm - Software delays based on 100MHz clock frequency.
;
;
;------------------------------------------------------------------------------------------
; Port definitions
;------------------------------------------------------------------------------------------
;
;
; UART (for connection with PicoTerm)
; -----------------------------------
;
; See 'PicoTerm_routines.psm' for I/O ports used with UART macros.
;
;
; I2C Interface
; -------------
;
; See 'kc705_i2c_devices.psm' for I/O ports used for I2C communication.
;
;
; PCA9548 (I2C Bus Switch) Control
; --------------------------------
;
; The PCA9548 has a hardware reset that is active Low. KCPSM6 can control this signal
; with a constant-optimised output port.
;
CONSTANT PCA9548_control_port, 02
CONSTANT PCA9548_reset_b, 00000001'b
;
;
;------------------------------------------------------------------------------------------
; Special Register usage
;------------------------------------------------------------------------------------------
;
; No registers are given special names in this program.
;
;
;------------------------------------------------------------------------------------------
; Scratch Pad Memory Locations (256 Bytes)
;------------------------------------------------------------------------------------------
;
; Scratch pad memory can be reduced to 64 or 128 bytes if desired.
;
;
; PicoTerm features
; -----------------
;
; See 'PicoTerm_routines.psm' for allocation of 18 memory locations.
; These are currently set to memory locations 00 to 12 hex inclusive.
;
;
;------------------------------------------------------------------------------------------
; Useful data constants
;------------------------------------------------------------------------------------------
;
;
;
;------------------------------------------------------------------------------------------
; Initialise the system
;------------------------------------------------------------------------------------------
;
; A delay of 1 second is implemented which is intended to give time for all the hardware
; to settle into a stable condition before starting to doing anything. This can be
; particularly beneficial when dealing with long cables where serial lines can take some
; time to reach the initial idle state following power being applied.
;
cold_start: CALL delay_1s
;
CALL reset_UART_macros ;Reset buffers in UART macros
;
CALL I2C_initialise ;initialise the I2C bus signals
;
; Generate a hardware reset pulse to the PCA9548 (I2C Bus Switch) to help recover from
; any bus fault conditions that may occur when experimenting with the KC705 board.
;
OUTPUTK ~PCA9548_reset_b, PCA9548_control_port ;active Low pulse
OUTPUTK PCA9548_reset_b, PCA9548_control_port
;
;
; Initialised PicoTerm display and display welcome messages
;
CALL PicoTerm_CLS
CALL welcome_message
;
;
;------------------------------------------------------------------------------------------
; Confirm connection has been made with PicoTerm
;------------------------------------------------------------------------------------------
;
; Before attempting to use any of the special features provided by PicoTerm it is a good
; idea to check that PicoTerm really is connected. This is where the Device Control String
; (DCS) request for a 'Ping' can be used. If a different terminal is being used then the
; plain text messages will be displayed as normal but the 'Ping' request will fail to
; return the response expected. So if this should occur a message will be displayed and
; this program will halt.
;
; Calling the 'PicoTerm_Ping' routine will transmit the Device Control String (DCS)
; to request the 'Ping' from PicoTerm. If PicoTerm is connected then it should respond
; with a DCS containing the (upper case) character 'P'. The response will be intercepted
; by the UART_RX routine and stored in scratch pad memory location 'PicoTerm_Response0'.
; It will take a short while for PicoTerm to respond so the 'Ping' check must wait whilst
; repeatedly calling the UART_RX routine.
;
; The transmission and reception of the 'Ping' DCS sequences (6 characters in total) would
; take ~520us at 115,200 baud rate. Since the program is only going to halt if no response
; occurs it will actually wait much longer. Each call of the UART_RX routine that results
; in its timeout will take ~2,000 clock cycles (~20us at 100MHz) so up to 50,000 (C350 hex)
; calls of UART_RX are made before giving up after approximately one second.
;
LOAD s0, 00 ;clear 'Ping' response location
STORE s0, PicoTerm_Response0
;
CALL PicoTerm_Ping ;request 'Ping' from PicoTerm
;
LOAD sB, C3 ;wait for 50,000 iterations
LOAD sA, 50 ; (~1 second at 100MHz)
;
wait_PT_ping: CALL UART_RX ;discard any characters received
FETCH s0, PicoTerm_Response0
COMPARE s0, "P" ;Test for valid 'Ping' response
JUMP Z, PicoTerm_detected ;continue normally
SUB sA, 01 ;decrement [sB,sA]
SUBCY sB, 00
JUMP NZ, wait_PT_ping
;
; 'Ping' response not received so transmit a text message.
; Note this would still be displayed on other terminals.
;
LOAD sB, no_detect_PT_msg'upper
LOAD sA, no_detect_PT_msg'lower
CALL send_message
PT_halt_here: JUMP PT_halt_here ;Halt program.
;
;
STRING not_PT1$, "ERROR - Unable to detect PicoTerm."
STRING not_PT2$, "Please use PicoTerm v1.30 or later with this design."
;
;
no_detect_PT_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, not_PT1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, not_PT2$
LOAD&RETURN s5, CR
LOAD&RETURN s5, NUL
;
; Once 'Ping' has confirmed that PicoTerm is present, close the 'PicoTerm DCS Transactions'
; window so that only the main window is open.
;
PicoTerm_detected: CALL PicoTerm_hide_DCS
;
;
;------------------------------------------------------------------------------------------
; Confirm I2C communication with M24C08 EEPROM device
;------------------------------------------------------------------------------------------
;
; When an I2C bus master (KCPSM6 in this case) transmits a byte of information, the
; receiving slave device is expected to respond with an acknowledgement bit (ACK).
; Therefore, observing this acknowledgement is a good indication that communication
; is possible with that slave. Of course, failure to observe an acknowledgement
; implies that something has gone wrong!
;
; In this design the objective is for KCPSM6 to communicate with the M24C08 ERPROM
; device. However, on the KC705, the Kintex-7 device only connects directly to a
; PCA9548 Bus Switch and then the M24C08 connects to 'CH3' of that switch. So to
; communicate with the EEPROM, KCPSM6 must first communicate with the Bus Switch
; and select 'CH3'.
;
; This section will first determine if I2C communication with the PCA9548 Bus Switch is
; possible. If it is, 'CH3' will be selected and an attempt will be made to to
; communicate with the M24C08 ERPROM. For the purposes of this reference design
; suitable text messages will be displayed depending on the results.
;
; The routines to communicate with the PCA9548 and the M24C08 devices are contained
; in 'kc705_i2c_devices.psm'. A communication failure is signified by the carry flag
; being set on return from any of these routines.
;
;
LOAD sB, I2C_check_msg'upper
LOAD sA, I2C_check_msg'lower
CALL send_message
;
; Attempt to select 'CH3' on the PCA9548 Bus Switch. Success will confirm
; communication with this device and select the EEPROM. As an additional test
; the channel selection value will be read back from the Bus Switch and
; checked.
;
LOAD sB, PCA9548_check_msg'upper
LOAD sA, PCA9548_check_msg'lower
CALL send_message
;
LOAD sD, 00001000'b ;'CH3' selection value
CALL PCA9548_mux_write ;write to PCA9548
JUMP C, I2C_failure ;comm's failure if carry=1
;
CALL PCA9548_mux_read ;read back switch control value
COMPARE sD, 00001000'b ;verify selection of 'CH3'
JUMP NZ, I2C_failure
;
CALL send_Pass
;
; An attempt is made to read from any memory location of the M24C08 ERPROM. Success
; will confirm communication via the Bus Switch with the EEPROM is possible.
;
LOAD sB, M24C08_check_msg'upper
LOAD sA, M24C08_check_msg'lower
CALL send_message
;
LOAD s8, 00 ;test address zero in [s8,s7]
LOAD s7, 00
CALL M24C08_read
JUMP C, I2C_failure ;comm's failure if carry=1
;
CALL send_Pass
JUMP M24C08_detected ;Everything Ok to continue
;
;
; I2C failure will display a message and halt the program.
;
I2C_failure: CALL PicoTerm_text_Red
LOAD sB, I2C_fail_msg'upper
LOAD sA, I2C_fail_msg'lower
CALL send_message
I2C_halt_here: JUMP I2C_halt_here ;Halt program.
;
;
; Text messages for this section
;
STRING I2C_check$, "Testing I2C communication"
STRING PCA9548_check$, " Bus Switch (PCA9548)... "
STRING M24C08_check$, " 1KB EEPROM (M24C08).... "
STRING I2C_fail1$, "ERROR - I2C unable to communicate!"
STRING I2C_fail2$, " Please try a complete power cycle of the KC705 board."
;
I2C_check_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, I2C_check$
LOAD&RETURN s5, NUL
;
PCA9548_check_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, PCA9548_check$
LOAD&RETURN s5, NUL
;
M24C08_check_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, M24C08_check$
LOAD&RETURN s5, NUL
;
I2C_fail_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, I2C_fail1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, I2C_fail2$
LOAD&RETURN s5, CR
LOAD&RETURN s5, NUL
;
M24C08_detected:
;
;
;------------------------------------------------------------------------------------------
; Main Program
;------------------------------------------------------------------------------------------
;
; The 'main' program allows the user to read, write and erase the N25Q128 device.
;
; WARNING - You are responsible for your own actions!
;
;
main_with_menu: CALL PicoTerm_text_Blue
CALL display_menu
;
; Display prompt and wait for user input.
; Then test input for valid section and either invoke operation or display message.
;
main_prompt: CALL PicoTerm_text_Blue
CALL send_CR ;prompt user to enter a command
CALL send_CR
LOAD s5, ">"
CALL UART_TX
CALL send_space
;
wait_main: CALL UART_RX ;wait for user input
JUMP Z, wait_main
CALL upper_case ;accept upper or lower case inputs
CALL UART_TX ;echo user input
;
COMPARE s5, "H" ;Help
JUMP Z, main_with_menu
;
COMPARE s5, "R" ;Read EEPROM
JUMP Z, read_EEPROM_command
;
COMPARE s5, "W" ;Write Byte
JUMP Z, write_byte_command
;
LOAD s5, "?" ;For all other inputs display ??
CALL UART_TX
CALL UART_TX
JUMP main_prompt
;
;
;------------------------------------------------------------------------------------------
; 'R' Read 1K Bytes Command
;------------------------------------------------------------------------------------------
;
; Read and display all 1024 bytes of data currently stored in the M24C08 EEPROM.
;
; In order to display all bytes in a way that is easy for the user to interpret, the
; memory map will be segmented into 4 blocks of 256 bytes. These will then be displayed
; in a square so that all information is visible on the screen at the same time.
;
; 000-0FF 200-2FF
;
; 100-1FF 300-3FF
;
; As a further aid, addresses will be displayed in a different colour to the data.
;
; Obviously this takes rather more PSM code to implement than that required simply to
; scan through the EEPROM but it is hoped that all PSM code is a useful example, and more
; significantly, this display does illustrates that EEPROM memory can be randomly accessed.
;
read_EEPROM_command: LOAD sD, 00001000'b ;Select PCA9548 'CH3' for M24C08
CALL PCA9548_mux_write
JUMP C, I2C_failure ;comm's failure if carry=1
;
; Display the address offset for each column in the form... +0 +1 +2 ... +F
;
CALL PicoTerm_text_Black
CALL send_CR
LOAD s8, 00
column_label_loop: TEST s8, 00001111'b ;Test for first column of each block
JUMP NZ, column_space
CALL send_space ;spaces to align with first column
CALL send_space
CALL send_space
CALL send_space
CALL send_space
CALL send_space
CALL send_space
CALL send_space
column_space: CALL send_space
LOAD s5, "+" ;display '+'
CALL UART_TX
LOAD s5, s8 ;convert lower nibble of 's8' to ASCII
AND s5, 00001111'b
CALL hex_to_ASCII
CALL UART_TX ;display digit
ADD s8, 01
COMPARE s8, 20
JUMP NZ, column_label_loop
CALL send_CR
;
; Each line will of the display will contain 16 bytes from two blocks.
; On the left side of the screen is the address range 000 to 1FF.
; On the right side of the screen is the address range 200 to 3FF.
;
; So starting with address 000, the first line reads and displays EEPROM data from
; 000 to 00F on the left hand side. It then skips to address 200 and reads and displays
; EEPROM data from 200 to 20F on the right hand side. Once the first line is complete
; the address skips back to 010 ready to being the second line.
;
LOAD s7, 00 ;10-bit EEPROM address in [s8,s7]
LOAD s8, 00
;
line_display_loop: CALL send_CR
COMPARE s7, 00 ;add a line space before the start of the
COMPARECY s8, 01 ;lower blocks starting at address 100
JUMP NZ, begin_line
CALL send_CR
begin_line: CALL send_space
CALL send_space
CALL send_space
CALL send_space
;
; Left Side
; Display address of first byte in black
;
CALL PicoTerm_text_Black ;display 10-bit address
LOAD s5, s8 ;convert lower nibble of 's8' to ASCII
CALL hex_to_ASCII
CALL UART_TX ;display MS-digit
LOAD s4, s7 ;convert and display two LS-Digits
CALL send_hex_byte
CALL send_space
CALL send_space
;
; Left Side
; Read and display 16 bytes of EEPROM data in Magenta
;
CALL PicoTerm_text_Magenta
left_side_loop: CALL M24C08_read ;read from [s8,s7] into 'sD'
JUMP C, I2C_failure ;comm's failure if carry=1
LOAD s4, sD ;display byte
CALL send_hex_byte
CALL send_space
ADD s7, 01 ;increment address
ADDCY s8, 00
TEST s7, 00001111'b ;test rollover of 16th byte
JUMP NZ, left_side_loop
;
; Right Side
; Display address of first byte in black
;
ADD s7, F0 ;Advance address by 200-010 hex
ADDCY s8, 01
CALL send_space
CALL send_space
CALL send_space
CALL PicoTerm_text_Black ;display 10-bit address
LOAD s5, s8 ;convert lower nibble of 's8' to ASCII
CALL hex_to_ASCII
CALL UART_TX ;display MS-digit
LOAD s4, s7 ;convert and display two LS-Digits
CALL send_hex_byte
CALL send_space
CALL send_space
;
; Right Side
; Read and display 16 bytes of EEPROM data in Magenta
;
CALL PicoTerm_text_Magenta
right_side_loop: CALL M24C08_read ;read from [s8,s7] into 'sD'
JUMP C, I2C_failure ;comm's failure if carry=1
LOAD s4, sD ;display byte
CALL send_hex_byte
CALL send_space
ADD s7, 01 ;increment address
ADDCY s8, 00
TEST s7, 00001111'b ;test rollover of 16th byte
JUMP NZ, right_side_loop
;
; Test for reaching the end of EEPROM memory.
; Last EEPROM address is 3FF so test for rollover to 0400.
;
COMPARE s8, 04
JUMP Z, main_prompt ;jump to main program when complete
;
SUB s8, 02 ;retard address by 200 hex
JUMP line_display_loop ;display next left side
;
;
;------------------------------------------------------------------------------------------
; 'W' Write Byte Command
;------------------------------------------------------------------------------------------
;
; Obtain a 10-bit address and 8-bit data value from the user and then write to EEPROM
; memory.
;
write_byte_command: LOAD sD, 00001000'b ;Select PCA9548 'CH3' for M24C08
CALL PCA9548_mux_write
JUMP C, I2C_failure ;comm's failure if carry=1
;
CALL obtain_address ;10-bit address in [s8,s7]
CALL obtain_data ;8-bit data value in sD
;
CALL M24C08_write ;write 'sD' into [s8,s7]
;
JUMP C, I2C_failure ;comm's failure if carry=1
;
CALL PicoTerm_text_Green
CALL send_Ok
JUMP main_prompt
;
;
;------------------------------------------------------------------------------------------
; Obtain 10-bit address from user
;------------------------------------------------------------------------------------------
;
; Prompt user to enter a 10-bit address and return it in [s8,s7].
; If user makes a mistake then keep prompting until they get it right!
;
obtain_address: CALL PicoTerm_text_Black
LOAD sB, prompt_address_msg'upper ;prompt for address
LOAD sA, prompt_address_msg'lower
CALL send_message
;
LOAD sE, 3'd ;obtain 3-digit value
CALL obtain_value ;12-bit value returned in [sB,sA]
JUMP C, bad_address_input ;Carry set for a bad hex value
;
TEST sB, 11111100'b ;check only 10-bit range
JUMP NZ, bad_address_input
;
LOAD s8, sB ;return 10-bit address
LOAD s7, sA ; in return it in [s8,s7]
RETURN
;
bad_address_input: CALL PicoTerm_text_Red
LOAD sB, bad_address_msg'upper
LOAD sA, bad_address_msg'lower
CALL send_message
JUMP obtain_address
;
;
; Text messages used in this section
;
STRING prompt_address$, "Please enter a 10-bit (3-digit hexadecimal) address > "
STRING bad_address$, "Sorry, that was not a valid address in the range 000 to 3FF hex!"
;
prompt_address_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, prompt_address$
LOAD&RETURN s5, NUL
;
bad_address_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, bad_address$
LOAD&RETURN s5, NUL
;
;
;------------------------------------------------------------------------------------------
; Obtain 8-bit data from user
;------------------------------------------------------------------------------------------
;
; Prompt user to enter an 8-bit data byte and return it in 'sD'.
; If user makes a mistake then keep prompting until they get it right!
;
obtain_data: CALL PicoTerm_text_Black
LOAD sB, prompt_data_msg'upper ;prompt for address
LOAD sA, prompt_data_msg'lower
CALL send_message
;
LOAD sE, 2'd ;obtain 2-digit value
CALL obtain_value ;8-bit value returned in sA
JUMP C, bad_data_input ;Carry set for a bad hex value
LOAD sD, sA ;Return data value in 'sD'
RETURN
;
bad_data_input: CALL PicoTerm_text_Red
LOAD sB, bad_data_msg'upper
LOAD sA, bad_data_msg'lower
CALL send_message
JUMP obtain_data
;
;
; Text messages used in this section
;
STRING prompt_data$, "Please enter an 8-bit data (2-digit hexadecimal) value > "
STRING bad_data$, "Sorry, that was not a valid 2-digit hexadecimal value!"
;
prompt_data_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, prompt_data$
LOAD&RETURN s5, NUL
;
bad_data_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, bad_data$
LOAD&RETURN s5, NUL
;
;
;------------------------------------------------------------------------------------------
; Welcome Message.
;------------------------------------------------------------------------------------------
;
; The welcome message includes a display of the version information available from the
; assembler and the 'hwbuild' from the instantiation of KCPSM6 in the hardware design.
;
welcome_message: LOAD sB, welcome_msg'upper
LOAD sA, welcome_msg'lower
CALL send_message
HWBUILD s5 ;hardware version defines ASCII letter
CALL UART_TX
CALL send_CR
RETURN
;
; Welcome message
;
STRING banner1$, " _ ______ ____ ____ __ __ __"
STRING banner2$, " | |/ / ___| _ \/ ___|| \/ |/ /_"
STRING banner3$, " | ' / | | |_) \___ \| |\/| | '_ \"
STRING banner4$, " | . \ |___| __/ ___) | | | | (_) )"
STRING banner5$, " |_|\_\____|_| |____/|_| |_|\___/"
;
; Welcome message
;
STRING welcome1$, "Reference Design: M24C08 EEPROM Controller for KC705 Board"
STRING welcome2$, " KCPSM6 implements an I2C 'Master'"
STRING welcome3$, "Assembly Date: "
STRING welcome4$, " Time: "
STRING welcome5$, "Assembler Version: "
STRING welcome6$, "Hardware Design: "
;
;
welcome_msg: LOAD&RETURN s5, banner1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner2$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner3$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner4$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner5$
LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome2$
LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome3$
LOAD&RETURN s5, datestamp$
LOAD&RETURN s5, welcome4$
LOAD&RETURN s5, timestamp$
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome5$
LOAD&RETURN s5, KCPSM6_version$
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome6$
LOAD&RETURN s5, NUL
;
;
;------------------------------------------------------------------------------------------
; Routine to transmit a simple 'Menu'.
;------------------------------------------------------------------------------------------
;
display_menu: LOAD sB, menu_msg'upper
LOAD sA, menu_msg'lower
CALL send_message
RETURN
;
; Menu message
;
STRING menu1$, "Menu"
STRING menu2$, " H - Display this menu"
STRING menu3$, " R - Read (all 1K Bytes)"
STRING menu4$, " W - Write (Byte)"
;
menu_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, menu1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, menu2$
LOAD&RETURN s5, CR
LOAD&RETURN s5, menu3$
LOAD&RETURN s5, CR
LOAD&RETURN s5, menu4$
LOAD&RETURN s5, CR
LOAD&RETURN s5, NUL
;
;
;------------------------------------------------------------------------------------------
; Send a message to the UART
;------------------------------------------------------------------------------------------
;
; A message is transmitted to the USB-UART.
; The start address of the message must be provided in [sB,sA].
; Terminate the transmission with a NULL character (00 hex).
;
send_message: CALL@ (sB, sA)
COMPARE s5, 00 ;terminate on NUL character
RETURN Z
CALL UART_TX
ADD sA, 1'd
ADDCY sB, 0'd
JUMP send_message
;
;
;------------------------------------------------------------------------------------------
; Send Carriage Return to UART
;------------------------------------------------------------------------------------------
;
; Registers used s0, s1, s2, and s5.
;
send_CR: LOAD s5, CR
JUMP UART_TX ;includes RETURN
;
;
;------------------------------------------------------------------------------------------
; Send Carriage Return, 'Ok' and Carriage Return to UART
;------------------------------------------------------------------------------------------
;
; Registers used s0, s1, s2, and s5.
;
send_Ok: CALL send_CR
LOAD s5, "O"
CALL UART_TX
LOAD s5, "k"
CALL UART_TX
JUMP send_CR ;includes RETURN
;
;
;------------------------------------------------------------------------------------------
; Send 'Pass' to UART
;------------------------------------------------------------------------------------------
;
; Registers used s0, s1, s2, and s5.
;
send_Pass: LOAD s5, "P"
CALL UART_TX
LOAD s5, "a"
CALL UART_TX
LOAD s5, "s"
CALL UART_TX
JUMP UART_TX ;includes RETURN
;
;------------------------------------------------------------------------------------------
; Send a Space to UART
;------------------------------------------------------------------------------------------
;
; Registers used s0, s1, s2, and s5.
;
send_space: LOAD s5, " "
JUMP UART_TX ;includes RETURN
;
;
;------------------------------------------------------------------------------------------
; Send Hex Value of Byte to UART
;------------------------------------------------------------------------------------------
;
; Value provided in register 's4' is sent as ASCII HEX to the UART transmitter.
;
; Registers used s0, s4 (preserved) and s5.
;
send_hex_byte: LOAD s5, s4 ;isolate upper nibble
SR0 s5
SR0 s5
SR0 s5
SR0 s5
CALL hex_to_ASCII ; convert to ASCII
CALL UART_TX ;send upper digit to UART
LOAD s5, s4 ;isolate lower nibble
AND s5, 0F
CALL hex_to_ASCII ; convert to ASCII
CALL UART_TX ;send lower digit to UART
RETURN
;
; Convert value 00 to 0F provided in 's5' into ASCII character in 's5'
;
; Register used s5
;
hex_to_ASCII: SUB s5, 0A ;test if value is in range 0 to 9
JUMP C, number_char
ADD s5, 07 ;ASCII char A to F in range 41 to 46
number_char: ADD s5, 3A ;ASCII char 0 to 9 in range 30 to 40
RETURN
;
;
;------------------------------------------------------------------------------------------
; Converts character to upper case
;------------------------------------------------------------------------------------------
;
; Tests and converts character in 's5' (if necessary).
;
; To convert character to upper case
;
; If the character is in the range 'a' to 'z', it is converted
; to the equivalent upper case character in the range 'A' to 'Z'.
; All other characters remain unchanged.
;
upper_case: COMPARE s5, "a" ;eliminate character codes below 'a' (61 hex)
RETURN C
COMPARE s5, 7B ;eliminate character codes above 'z' (7A hex)
RETURN NC
AND s5, 11011111'b ;force bit5 Low to convert to upper case
RETURN
;
;
;------------------------------------------------------------------------------------------
; Convert ASCII character to an equivalent HEX value.
;------------------------------------------------------------------------------------------
;
; Converts the ASCII character presented in 's5' to an equivalent HEX value.
; If character is not valid for hex, then CARRY is set on return.
;
; Register used s5
;
ASCII_to_hex: ADD s5, B9 ;test for above ASCII code 46 ('F')
RETURN C
SUB s5, E9 ;normalise 0 to 9 with A-F in 11 to 16 hex
RETURN C ;reject below ASCII code 30 ('0')
SUB s5, 11 ;isolate A-F down to 00 to 05 hex
JUMP NC, ASCII_letter
ADD s5, 07 ;test for above ASCII code 46 ('F')
RETURN C
SUB s5, F6 ;convert to range 00 to 09
RETURN
ASCII_letter: ADD s5, 0A ;convert to range 0A to 0F
RETURN
;
;
;------------------------------------------------------------------------------------------
; Read ASCII-HEX value up to 8-digits (for 32-bit value) from UART
;------------------------------------------------------------------------------------------
;
; Read up to 8 hex characters from UART and convert to a binary value in the [sD,sC,sB,sA]
; register set. The number of characters to be read must be defined in sE. When less than
; 8 characters are read the value is returned in the least significant bits of the register
; set with the 8-bits above the defined value being zero to ensure ensuring that the upper
; nibble will be zero if an odd number of digits are read.
;
; If any character received from the UART is not in the range 0 to F then the routine will
; end immediately with the CARRY flag set and this should be checked my the calling process
; upon return.
;
obtain_value: LOAD sA, 00 ;initialise potentially unused bits to zero
obtain_digit: CALL UART_RX ;wait for a character and return in s5
JUMP Z, obtain_digit ;continue to wait if timeout occurs
CALL UART_TX ;echo character as entered
CALL upper_case ;convert to upper case if necessary
CALL ASCII_to_hex ;convert value in s5 to hex nibble
RETURN C ;If invalid hex digit then return immediately
LOAD s0, 4'd ;shift [sD,sC,sB,sA] left by 4 bits
build_value: SL0 sA ; to make space for new digit value
SLA sB
SLA sC
SLA sD
SUB s0, 1'd
JUMP NZ, build_value
OR sA, s5 ;merge value of new digit into existing value
SUB sE, 01 ;count number of digits obtained
JUMP NZ, obtain_digit
RETURN
;
;
;------------------------------------------------------------------------------------------
; Include PSM files
;------------------------------------------------------------------------------------------
;
; The INCLUDE directive enables commonly routines to be kept in their own PSM files and
; easily reused in different programs (i.e. avoiding 'cut and paste'). It also allows
; each PSM to remain a more manageable size.
;
;
; Routines that implement interface with UART macros and control PicoTerm.
; ------------------------------------------------------------------------
;
INCLUDE "PicoTerm_routines.psm"
;
;
; Software Delays
; ---------------
;
INCLUDE "soft_delays_100mhz.psm"
;
;
; Fundamental I2C signaling
; -------------------------
;
INCLUDE "i2c_routines.psm"
;
;
; I2C communication with PCA9548 and M24C08 on the KC705 board
; ------------------------------------------------------------
;
INCLUDE "kc705_i2c_devices.psm"
;
;
;------------------------------------------------------------------------------------------
; Interrupt Service Routine (ISR)
;------------------------------------------------------------------------------------------
;
; Interrupts are not currently used in this program but in preparation the location of
; the ISR has been defined to corresponding with the 'interrupt_vector' address defined
; in the instantiation of KCPSM6. In this instance the vector is 7F0 hex which means there
; are 16 instructions available before reaching the end of a 2K program memory. Of course
; this can all be modified.
;
ADDRESS 7F0
;
;
ISR: RETURNI DISABLE
;
;
;------------------------------------------------------------------------------------------
; End of Program
;------------------------------------------------------------------------------------------
;

View File

@ -0,0 +1,109 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2012-2013, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; PicoBlaze Reference Design.
;
;
; Ken Chapman - Xilinx Ltd
;
; 6th September 2012 - Initial version
; 18th March 2013 - Addition of 20ms delay
;
; This file contains routines that implement delays in software. It should be recognised
; that the delay periods are the result of executing instructions, and because every
; instruction takes 2 clock cycles to execute, it is possible to determine the exact
; delay period. However, besides the obvious dependency on the clock frequency, it
; should also be recognised that any interrupts to KCPSM6 (or use of sleep mode) will
; impact the timing. In general, it is better only to use soft delay routines in
; situations where approximate timing is adequate; in those situations KCPSM6 will often
; exceed your requirements.
;
;
;------------------------------------------------------------------------------------------
; Software Delays based on 100MHz clock
;------------------------------------------------------------------------------------------
;
; The number of iterations of a delay loop required to form each delay required are
; loaded into the register set [s2,s1,s0] and then the delay loop is started.
;
; Registers used s0, s1, s2
;
; 1ms is 10,000 x 100ns (10,000 = 002710 hex)
;
delay_1ms: LOAD s2, 00
LOAD s1, 27
LOAD s0, 10
JUMP software_delay
;
; 20ms is 200,000 x 100ns (200,000 = 030D40 hex)
;
delay_20ms: LOAD s2, 03
LOAD s1, 0D
LOAD s0, 40
JUMP software_delay
;
;
; 1s is 10,000,000 x 100ns (10,000,000 = 989680 hex)
;
delay_1s: LOAD s2, 98
LOAD s1, 96
LOAD s0, 80
JUMP software_delay
;
; The delay loop decrements [s2,s1,s0] until it reaches zero
; Each decrement cycle is 5 instructions which is 10 clock cycles (100ns at 100MHz)
;
software_delay: LOAD s0, s0 ;pad loop to make it 10 clock cycles (5 instructions)
SUB s0, 1'd
SUBCY s1, 0'd
SUBCY s2, 0'd
JUMP NZ, software_delay
RETURN
;
;
;------------------------------------------------------------------------------------------
; End of 'soft_delays_100mhz.psm'
;------------------------------------------------------------------------------------------
;

View File

@ -0,0 +1,547 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2013-2014, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; PicoBlaze Reference Design.
;
;
; Routines for ICAPE2 Communication, Control and Monitoring
;
; Ken Chapman - Xilinx Ltd
;
; 18th August 2014 - Initial Version
;
;
; NOTE - This is not a standalone PSM file. Include this file in a program that
; then calls these routines and works with the values in scratch pad memory.
;
; INCLUDE "ICAPE2_routines.psm"
;
;
; IMPORTANT - These routines interact with input and output ports which must
; be appropriately defined to interface with ICAPE2. The CONSTANT
; directives defined below must correspond with the port assignments.
;
;
; INTRODUCTION
; ------------
;
; This file implements two routines that facilitates reads and writes from and to ICAPE2.
;
; This file also includes routines which help to implement ICAPE2 transactions.
;
;------------------------------------------------------------------------------------------
; Hardware Constants
;------------------------------------------------------------------------------------------
;
; The following constants define the input and output ports allocated to the ICAPE2
; interface. These constants reflect the ports used in the 'kc705_kcpsm6_icap.vhd'
; reference design file and should be modified if different ports are allocated in your
; own designs.
;
; Prior to initiating a write transaction a 32-bit data word should be present to
; ICAPE2 using the following output ports.
;
CONSTANT icap_din0, 04 ; icap_din[7:0]
CONSTANT icap_din1, 05 ; icap_din[15:8]
CONSTANT icap_din2, 06 ; icap_din[23:16]
CONSTANT icap_din3, 07 ; icap_din[31:24]
;
; Following a read transaction a 32-bit data word can be read from ICAPE2 using these
; input ports.
;
CONSTANT icap_dout0, 04 ; icap_dout[7:0]
CONSTANT icap_dout1, 05 ; icap_dout[15:8]
CONSTANT icap_dout2, 06 ; icap_dout[23:16]
CONSTANT icap_dout3, 07 ; icap_dout[31:24]
;
; An ICAPE2 word read or word write is initated by an OUTPUTK instruction to the
; following port which generates an active Low pulse on the CSIB input to ICAPE2.
; At the same time, Bit0 defines if the operation is read(1) or write(0) by setting
; then RDWRB input to ICAPE2.
;
CONSTANT icap_trigger_port, 02
CONSTANT icap_read_operation, 00000001'b ; Read (RDWRB = 1)
CONSTANT icap_write_operation, 00000000'b ; Write (RDWRB = 0)
;
;
;------------------------------------------------------------------------------------------
; Scratch Pad Memory
;------------------------------------------------------------------------------------------
;
; The CONSTANT directives below define the allocation of scratch pad memory locations
; used to store information associated with ICAPE2.
;
;
CONSTANT ICAPE2_word0, 20 ; bits[7:0]
CONSTANT ICAPE2_word1, 21 ; bits[15:8]
CONSTANT ICAPE2_word2, 22 ; bits[23:16]
CONSTANT ICAPE2_word3, 23 ; bits[31:24]
;
CONSTANT IDCODE_word0, 24 ; bits[7:0]
CONSTANT IDCODE_word1, 25 ; bits[15:8]
CONSTANT IDCODE_word2, 26 ; bits[23:16]
CONSTANT IDCODE_word3, 27 ; bits[31:24]
;
CONSTANT FAR_word0, 28 ; bits[7:0]
CONSTANT FAR_word1, 29 ; bits[15:8]
CONSTANT FAR_word2, 2A ; bits[23:16]
CONSTANT FAR_word3, 2B ; bits[31:24]
;
;
;------------------------------------------------------------------------------------------
; Routine to read a 32-bit word from ICAPE2
;------------------------------------------------------------------------------------------
;
; The 32-bit word is returned in [sF,sE,sD,sC] and stored in scratch pad memory locations
; ICAPE2_word3, ICAPE2_word2, ICAPE2_word1 and ICAPE2_word0.
;
; As described and definded in 'kc705_kcpsm6_icap.vhd', ICAPE2 has a read latency of three
; clock cycles. The interface circuit captures the 32-bit value in a register so that
; KCPSM6 can then read it one byte at a time. Note the short delay present in the routine
; below that allows for the latency of ICAPE2 and the capture of the value being read.
;
; Registers used sC, sD, sE and sF.
;
;
read_word_from_ICAPE2: OUTPUTK icap_read_operation, icap_trigger_port
LOAD sC, sC ;time to complete read operation
LOAD sC, sC
INPUT sC, icap_dout0 ;read 32-bit word
INPUT sD, icap_dout1
INPUT sE, icap_dout2
INPUT sF, icap_dout3
STORE sC, ICAPE2_word0 ;store 32-bit word
STORE sD, ICAPE2_word1
STORE sE, ICAPE2_word2
STORE sF, ICAPE2_word3
RETURN
;
;
;------------------------------------------------------------------------------------------
; Routine to write a 32-bit word to ICAPE2
;------------------------------------------------------------------------------------------
;
; A 32-bit word must be provided in [sF,sE,sD,sC].
;
; Registers used sC, sD, sE and sF (all preserved).
;
write_word_to_ICAPE2: OUTPUT sF, icap_din3
OUTPUT sE, icap_din2
OUTPUT sD, icap_din1
OUTPUT sC, icap_din0
OUTPUTK icap_write_operation, icap_trigger_port
RETURN
;
;
;------------------------------------------------------------------------------------------
; Routines to write various 32-bit words to ICAPE2
;------------------------------------------------------------------------------------------
;
; In each case the value of the 32-bit word is defined in [sF,sE,sD,sC] and then passed
; to the 'write_word_to_ICAPE2' routine (which includes RETURN).
;
; Registers used sC, sD, sE and sF.
;
;
Dummy_to_ICAPE2: LOAD sF, FF ; Dummy (or idle) = FFFFFFFF
LOAD sE, FF
LOAD sD, FF
LOAD sC, FF
JUMP write_word_to_ICAPE2
;
;
NOOP_to_ICAPE2: LOAD sF, 20 ; NOOP = 20000000
LOAD sE, 00
LOAD sD, 00
LOAD sC, 00
JUMP write_word_to_ICAPE2
;
;
SYNC_to_ICAPE2: LOAD sF, AA ; SYNC = AA995566
LOAD sE, 99
LOAD sD, 55
LOAD sC, 66
JUMP write_word_to_ICAPE2
;
;
CMD_to_ICAPE2: LOAD sF, 30 ; Type 1 write of one word to CMD = 30008001
LOAD sE, 00
LOAD sD, 80
LOAD sC, 01
JUMP write_word_to_ICAPE2
;
;
DESYNC_to_ICAPE2: LOAD sF, 00 ; DESYNC (write to CMD) = 0000000D
LOAD sE, 00
LOAD sD, 00
LOAD sC, 0D
JUMP write_word_to_ICAPE2
;
;
read_IDCODE_to_ICAPE2: LOAD sF, 28 ; Type 1 read of one word from IDCODE = 28018001
LOAD sE, 01
LOAD sD, 80
LOAD sC, 01
JUMP write_word_to_ICAPE2
;
;
read_CTL0_to_ICAPE2: LOAD sF, 28 ; Type 1 read of one word from CTL0 = 2800A001
LOAD sE, 00
LOAD sD, A0
LOAD sC, 01
JUMP write_word_to_ICAPE2
;
;
read_STAT_to_ICAPE2: LOAD sF, 28 ; Type 1 read of one word from STAT = 2800E001
LOAD sE, 00
LOAD sD, E0
LOAD sC, 01
JUMP write_word_to_ICAPE2
;
;
read_COR0_to_ICAPE2: LOAD sF, 28 ; Type 1 read of one word from COR0 = 28012001
LOAD sE, 01
LOAD sD, 20
LOAD sC, 01
JUMP write_word_to_ICAPE2
;
;
read_COR1_to_ICAPE2: LOAD sF, 28 ; Type 1 read of one word from COR1 = 2801C001
LOAD sE, 01
LOAD sD, C0
LOAD sC, 01
JUMP write_word_to_ICAPE2
;
;
read_WBSTAR_to_ICAPE2: LOAD sF, 28 ; Type 1 read of one word from WBSTAR = 28020001
LOAD sE, 02
LOAD sD, 00
LOAD sC, 01
JUMP write_word_to_ICAPE2
;
;
read_BOOTSTS_to_ICAPE2: LOAD sF, 28 ; Type 1 read of one word from BOOTSTS = 2802C001
LOAD sE, 02
LOAD sD, C0
LOAD sC, 01
JUMP write_word_to_ICAPE2
;
;
read_FAR_to_ICAPE2: LOAD sF, 28 ; Type 1 read of one word from FAR = 28002001
LOAD sE, 00
LOAD sD, 20
LOAD sC, 01
JUMP write_word_to_ICAPE2
;
;
;------------------------------------------------------------------------------------------
; SYNC sequence
;------------------------------------------------------------------------------------------
;
; Open communication with ICAP
;
SYNC_sequence_to_ICAPE2: CALL NOOP_to_ICAPE2 ;NOOP
CALL SYNC_to_ICAPE2 ;SYNC
CALL NOOP_to_ICAPE2 ;NOOP
JUMP NOOP_to_ICAPE2 ;NOOP (includes RETURN)
;
;
;------------------------------------------------------------------------------------------
; DESYNC sequence
;------------------------------------------------------------------------------------------
;
; Close communication with ICAPE2
;
DESYNC_sequence_to_ICAPE2: CALL NOOP_to_ICAPE2 ;NOOP
CALL CMD_to_ICAPE2 ;Type 1 write of one word to CMD
CALL DESYNC_to_ICAPE2 ;DESYNC command
CALL NOOP_to_ICAPE2 ;NOOP
CALL NOOP_to_ICAPE2 ;NOOP
JUMP Dummy_to_ICAPE2 ;Dummy (idle) (includes RETURN)
;
;
;------------------------------------------------------------------------------------------
; Read IDCODE sequence
;------------------------------------------------------------------------------------------
;
; Complete sequence to open communication with ICAPE2, read the IDCODE register and close
; communication with ICAPE2
;
; The value of IDCODE is stored in scatch pad memory locations ICAPE2_word0, ICAPE2_word1,
; ICAPE2_word2 and ICAPE2_word3. This useful information is also stored in IDCODE_word0,
; IDCODE_word1, IDCODE_word2 and IDCODE_word3 for future used (i.e. when writing frames).
;
read_IDCODE_sequence: CALL SYNC_sequence_to_ICAPE2 ;SYNC sequence
CALL read_IDCODE_to_ICAPE2 ;Type 1 read of one word from IDCODE
CALL NOOP_to_ICAPE2 ;NOOP
CALL NOOP_to_ICAPE2 ;NOOP
CALL read_word_from_ICAPE2 ;read and store word
STORE sC, IDCODE_word0 ;store copy of IDCODE
STORE sD, IDCODE_word1
STORE sE, IDCODE_word2
STORE sF, IDCODE_word3
JUMP DESYNC_sequence_to_ICAPE2 ;DESYNC sequence (includes RETURN)
;
;
;------------------------------------------------------------------------------------------
; Read CTL0 sequence
;------------------------------------------------------------------------------------------
;
; Complete sequence to open communication with ICAPE2, read the CTL0 register and close
; communication with ICAPE2
;
; The value of CTL0 is stored in scatch pad memory locations ICAPE2_word3, ICAPE2_word2,
; ICAPE2_word1 and ICAPE2_word0.
;
read_CTL0_sequence: CALL SYNC_sequence_to_ICAPE2 ;SYNC sequence
CALL read_CTL0_to_ICAPE2 ;Type 1 read of one word from CTL0
CALL NOOP_to_ICAPE2 ;NOOP
CALL NOOP_to_ICAPE2 ;NOOP
CALL read_word_from_ICAPE2 ;read and store word
JUMP DESYNC_sequence_to_ICAPE2 ;DESYNC sequence (includes RETURN)
;
;
;------------------------------------------------------------------------------------------
; Read STAT sequence
;------------------------------------------------------------------------------------------
;
; Complete sequence to open communication with ICAPE2, read the STAT register and close
; communication with ICAPE2
;
; The value of STAT is stored in scatch pad memory locations ICAPE2_word3, ICAPE2_word2,
; ICAPE2_word1 and ICAPE2_word0.
;
read_STAT_sequence: CALL SYNC_sequence_to_ICAPE2 ;SYNC sequence
CALL read_STAT_to_ICAPE2 ;Type 1 read of one word from STAT
CALL NOOP_to_ICAPE2 ;NOOP
CALL NOOP_to_ICAPE2 ;NOOP
CALL read_word_from_ICAPE2 ;read and store word
JUMP DESYNC_sequence_to_ICAPE2 ;DESYNC sequence (includes RETURN)
;
;
;------------------------------------------------------------------------------------------
; Read COR0 sequence
;------------------------------------------------------------------------------------------
;
; Complete sequence to open communication with ICAPE2, read the COR0 register and close
; communication with ICAPE2
;
; The value of COR0 is stored in scatch pad memory locations ICAPE2_word3, ICAPE2_word2,
; ICAPE2_word1 and ICAPE2_word0.
;
read_COR0_sequence: CALL SYNC_sequence_to_ICAPE2 ;SYNC sequence
CALL read_COR0_to_ICAPE2 ;Type 1 read of one word from COR0
CALL NOOP_to_ICAPE2 ;NOOP
CALL NOOP_to_ICAPE2 ;NOOP
CALL read_word_from_ICAPE2 ;read and store word
JUMP DESYNC_sequence_to_ICAPE2 ;DESYNC sequence (includes RETURN)
;
;
;------------------------------------------------------------------------------------------
; Read COR1 sequence
;------------------------------------------------------------------------------------------
;
; Complete sequence to open communication with ICAPE2, read the COR1 register and close
; communication with ICAPE2
;
; The value of COR1 is stored in scatch pad memory locations ICAPE2_word3, ICAPE2_word2,
; ICAPE2_word1 and ICAPE2_word0.
;
read_COR1_sequence: CALL SYNC_sequence_to_ICAPE2 ;SYNC sequence
CALL read_COR1_to_ICAPE2 ;Type 1 read of one word from COR1
CALL NOOP_to_ICAPE2 ;NOOP
CALL NOOP_to_ICAPE2 ;NOOP
CALL read_word_from_ICAPE2 ;read and store word
JUMP DESYNC_sequence_to_ICAPE2 ;DESYNC sequence (includes RETURN)
;
;
;------------------------------------------------------------------------------------------
; Write COR1 sequence
;------------------------------------------------------------------------------------------
;
; Complete sequence to open communication with ICAPE2, write the COR1 register with a value
; and close communication with ICAPE2
;
; The value to be written to COR1 should be stored in scatch pad memory locations
; ICAPE2_word3, ICAPE2_word2, ICAPE2_word1 and ICAPE2_word0 before calling this routine.
;
write_COR1_sequence: CALL SYNC_sequence_to_ICAPE2 ;SYNC sequence
LOAD sF, 30 ;Type 1 write of one word to COR1 register
LOAD sE, 01 ;03001C001
LOAD sD, C0
LOAD sC, 01
CALL write_word_to_ICAPE2
FETCH sF, ICAPE2_word3 ;Fetch value to be written to COR1
FETCH sE, ICAPE2_word2
FETCH sD, ICAPE2_word1
FETCH sC, ICAPE2_word0
CALL write_word_to_ICAPE2
CALL NOOP_to_ICAPE2 ;NOOP
CALL NOOP_to_ICAPE2 ;NOOP
JUMP DESYNC_sequence_to_ICAPE2 ;DESYNC sequence (includes RETURN)
;
;
;------------------------------------------------------------------------------------------
; Read WBSTAR sequence
;------------------------------------------------------------------------------------------
;
; Complete sequence to open communication with ICAPE2, read the WBSTAR register and close
; communication with ICAPE2
;
; The value of WBSTAR is stored in scatch pad memory locations ICAPE2_word3, ICAPE2_word2,
; ICAPE2_word1 and ICAPE2_word0.
;
read_WBSTAR_sequence: CALL SYNC_sequence_to_ICAPE2 ;SYNC sequence
CALL read_WBSTAR_to_ICAPE2 ;Type 1 read of one word from WBSTAR
CALL NOOP_to_ICAPE2 ;NOOP
CALL NOOP_to_ICAPE2 ;NOOP
CALL read_word_from_ICAPE2 ;read and store word
JUMP DESYNC_sequence_to_ICAPE2 ;DESYNC sequence (includes RETURN)
;
;
;------------------------------------------------------------------------------------------
; Read BOOTSTS sequence
;------------------------------------------------------------------------------------------
;
; Complete sequence to open communication with ICAPE2, read the BOOTSTS register and close
; communication with ICAPE2
;
; The value of BOOTSTS is stored in scatch pad memory locations ICAPE2_word3, ICAPE2_word2,
; ICAPE2_word1 and ICAPE2_word0.
;
read_BOOTSTS_sequence: CALL SYNC_sequence_to_ICAPE2 ;SYNC sequence
CALL read_BOOTSTS_to_ICAPE2 ;Type 1 read of one word from BOOTSTS
CALL NOOP_to_ICAPE2 ;NOOP
CALL NOOP_to_ICAPE2 ;NOOP
CALL read_word_from_ICAPE2 ;read and store word
JUMP DESYNC_sequence_to_ICAPE2 ;DESYNC sequence (includes RETURN)
;
;
;------------------------------------------------------------------------------------------
; Read BOOTSTS sequence
;------------------------------------------------------------------------------------------
;
; Complete sequence to open communication with ICAPE2, read the FAR register and close
; communication with ICAPE2
;
; The value of FAR is stored in scatch pad memory locations ICAPE2_word3, ICAPE2_word2,
; ICAPE2_word1 and ICAPE2_word0.
;
read_FAR_sequence: CALL SYNC_sequence_to_ICAPE2 ;SYNC sequence
CALL read_FAR_to_ICAPE2 ;Type 1 read of one word from FAR
CALL NOOP_to_ICAPE2 ;NOOP
CALL NOOP_to_ICAPE2 ;NOOP
CALL read_word_from_ICAPE2 ;read and store word
JUMP DESYNC_sequence_to_ICAPE2 ;DESYNC sequence (includes RETURN)
;
;
;------------------------------------------------------------------------------------------
; Write FAR sequence
;------------------------------------------------------------------------------------------
;
; Complete sequence to open communication with ICAPE2, write the FAR register with a value
; and close communication with ICAPE2
;
; The value to be written to FAR should be stored in scatch pad memory locations
; FAR_word3, FAR_word2, FAR_word1 and FAR_word0 before calling this routine.
;
; NOTE - If Readback CRC scanning is enabled then the contents of FAR will be modified
; after the DESYNC sequence.
;
write_FAR_sequence: CALL SYNC_sequence_to_ICAPE2 ;SYNC sequence
LOAD sF, 30 ;Type 1 write of one word to FAR register
LOAD sE, 00 ;03002001
LOAD sD, 20
LOAD sC, 01
CALL write_word_to_ICAPE2
FETCH sF, FAR_word3 ;Fetch value to be written to FAR
FETCH sE, FAR_word2
FETCH sD, FAR_word1
FETCH sC, FAR_word0
CALL write_word_to_ICAPE2
CALL NOOP_to_ICAPE2 ;NOOP
CALL NOOP_to_ICAPE2 ;NOOP
JUMP DESYNC_sequence_to_ICAPE2 ;DESYNC sequence (includes RETURN)
;
;
;------------------------------------------------------------------------------------------
; The following tables define 32-bit words that will written to ICAPE2
;------------------------------------------------------------------------------------------
;
TABLE Dummy#, [FF,FF,FF,FF] ;Dummy word
TABLE NOOP#, [20,00,00,00] ;NOOP
TABLE Bus_Sync#, [00,00,00,BB] ;Bus width sync word
TABLE Bus_Detect#, [11,22,00,44] ;Bus width detect
TABLE SYNC#, [AA,99,55,66] ;SYNC word
TABLE CMD#, [30,00,80,01] ;Type 1 write of one word to CMD
TABLE DESYNC#, [00,00,00,0D] ;DESYNC (write to CMD)
TABLE read_IDCODE#, [28,01,80,01] ;Type 1 read of one word from IDCODE
TABLE read_STAT#, [28,00,E0,01] ;Type 1 read of one word from STAT
TABLE read_FAR#, [28,00,20,01] ;Type 1 read of one word from FAR
TABLE read_COR1#, [28,01,C0,01] ;Type 1 read of one word from COR1
TABLE FAR#, [30,00,20,01] ;Type 1 write of one word to FAR
;
;
;------------------------------------------------------------------------------------------
; ICAPE2 Idle mode
;------------------------------------------------------------------------------------------
;
ICAPE2_idle: LOAD sF, FF
LOAD sE, FF
LOAD sD, FF
LOAD sC, FF
;
OUTPUT sF, icap_dout3
OUTPUT sE, icap_dout2
OUTPUT sD, icap_dout1
OUTPUT sC, icap_dout0
RETURN
;
;
;------------------------------------------------------------------------------------------
; End of 'ICAPE2_routines.psm'
;------------------------------------------------------------------------------------------
;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,216 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2014, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; PicoBlaze Reference Design.
;
;
; Routines for communication with a RAM of 4096 bytes. The RAM is implemented using a
; synchronous BRAM (36kb) connected to KCPSM6 input and output ports.
;
;
; Ken Chapman - Xilinx Ltd
;
; 5th September 2014 - Initial Version
;
;
; NOTE - This is not a standalone PSM file. Include this file in a program that
; then calls these routines.
;
; INCLUDE "RAM_4096x8_routines.psm"
;
;
; IMPORTANT - These routines interact with input and output ports which must
; be appropriately defined to interface with the external memory.
; The CONSTANT directives defined below must correspond with the
; port assignments.
;
;
; INTRODUCTION
; ------------
;
; This file implements a pair of routines that simply write and read bytes of data to and
; from the external memory as specified addresses. A second pair of routines facilitate
; the reading and writing of 32-bit words.
;
;
;------------------------------------------------------------------------------------------
; Hardware Constants
;------------------------------------------------------------------------------------------
;
; The following constants define the input and output ports allocated to the RAM
; interface. These constants reflect the ports used in the 'kc705_kcpsm6_icap.vhd'
; reference design file and should be modified if different ports are allocated in your
; own designs.
;
; Prior to initiating a write transaction a 32-bit data word should be present to
; ICAPE2 using the following output ports.
;
; The 12-bit address is set by writing to two output ports.
;
CONSTANT RAM_address0_port, 08 ;ram_address[7:0]
CONSTANT RAM_address1_port, 10 ;ram_address[11:8]
;
; Data is then written to or read from the current address using the following ports.
; (An OUTPUT to 'write_to_RAM_port' generates a write enable pulse to the BRAM)
;
CONSTANT write_to_RAM_port, 20
CONSTANT read_from_RAM_port, 14
;
;
;------------------------------------------------------------------------------------------
; Write and Read bytes to and from external RAM (4096 x 8-bit)
;------------------------------------------------------------------------------------------
;
; The following routines write and read bytes to and from the 4096 x 8 RAM connected to
; input and output ports. The 12-bit RAM address must be defined by [s9,s8] and the byte
; is is transfered between register 's5' and the memory.
;
; Read from RAM
; -------------
;
; The BRAM is synchronous so it takes a clock cycle after the address has been defined for
; the output of the BRAM to present the memory contents at that location. The KCPSM6 input
; ports are implemented by a pipelined multiplexer so there must be a small delay before
; the INPUT instruction is executed to allow the desired data from the BRAM to be selected
; and read by KCPSM6.
;
read_byte_from_RAM: OUTPUT s8, RAM_address0_port ;set address
OUTPUT s9, RAM_address1_port
LOAD s5, s5 ;2 clock cycle delay
INPUT s5, read_from_RAM_port ;read from memory
RETURN
;
;
; Write to RAM
; ------------
;
write_byte_to_RAM: OUTPUT s8, RAM_address0_port ;set address
OUTPUT s9, RAM_address1_port
OUTPUT s5, write_to_RAM_port ;write to memory
RETURN
;
;
;------------------------------------------------------------------------------------------
; Write and Read 32-bit words to and from external RAM (4096 x 8-bit)
;------------------------------------------------------------------------------------------
;
; The following routines write and read 32-bit words to and from the 4096 x 8 RAM connected
; to input and output ports. Each word requires 4 bytes (4 locations) in the memory. Words
; will be stored with the least significant byte at the lower address of four successive
; locations. It is generally considered good practice to align the words such that the
; address of the least significant byte ends with '00' (e.g. Addresses 0000, 0004, 0008,
; 000C, 0010 hex etc).
;
; The 12-bit RAM address is defined by [s9,s8]. This can be set prior to calling these
; routines or the current value used providing it is suitable and has not been modified
; by other program activity. The 'reset_RAM_address' routine can be used to reset the
; address.
;
; During a write operation, a 32-bit word provided in [sF,sE,sD,sC] is written to four
; successive memory locations.
;
; During a read operation, a 32-bit word is read from four successive memory locations and
; returned in [sF,sE,sD,sC].
;
; In both cases, the address defined by [s9,s8] is incremented. On return, the address will
; will correspond with the location associated with the first byte of the next word.
;
;
; Reset RAM address
; -----------------
;
; This routine will set the address presented to the external RAM to zero and will return
; with [s9,s8] = 0000.
;
;
reset_RAM_address: LOAD s8, FF ;[s9,s8] = FFFF
LOAD s9, FF
JUMP increment_RAM_address ;advance [s9,s8] to 0000 and set address (includes RETURN)
;
;
; Read from RAM
; -------------
;
read_word_from_RAM: INPUT sC, read_from_RAM_port
CALL increment_RAM_address
INPUT sD, read_from_RAM_port
CALL increment_RAM_address
INPUT sE, read_from_RAM_port
CALL increment_RAM_address
INPUT sF, read_from_RAM_port
JUMP increment_RAM_address ;includes RETURN
;
;
; Write to RAM
; ------------
;
write_word_to_RAM: OUTPUT sC, write_to_RAM_port
CALL increment_RAM_address
OUTPUT sD, write_to_RAM_port
CALL increment_RAM_address
OUTPUT sE, write_to_RAM_port
CALL increment_RAM_address
OUTPUT sF, write_to_RAM_port
JUMP increment_RAM_address ;includes RETURN
;
;
; Routine to increment and set RAM address.
;
; Note that during the 2 clock cycles it takes for the RETURN instruction
; to execute, the synchronous BRAM is presenting the memory contents at its
; output so that it is ready to be read by KCPSM6.
;
increment_RAM_address: ADD s8, 01 ;increment [s9,s8]
ADDCY s9, 00
OUTPUT s8, RAM_address0_port ;set address
OUTPUT s9, RAM_address1_port
RETURN
;
;
;------------------------------------------------------------------------------------------
; End of 'RAM_4096x8_routines.psm'
;------------------------------------------------------------------------------------------
;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,233 @@
#
#------------------------------------------------------------------------------------------
# Copyright 2012-2014, Xilinx, Inc.
# This file contains confidential and proprietary information of Xilinx, Inc. and is
# protected under U.S. and international copyright and other intellectual property laws.
#------------------------------------------------------------------------------------------
#
# Disclaimer:
# This disclaimer is not a license and does not grant any rights to the materials
# distributed herewith. Except as otherwise provided in a valid license issued to
# you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
# MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
# DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
# INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
# OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
# (whether in contract or tort, including negligence, or under any other theory
# of liability) for any loss or damage of any kind or nature related to, arising
# under or in connection with these materials, including for any direct, or any
# indirect, special, incidental, or consequential loss or damage (including loss
# of data, profits, goodwill, or any type of loss or damage suffered as a result
# of any action brought by a third party) even if such damage or loss was
# reasonably foreseeable or Xilinx had been advised of the possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-safe, or for use in any
# application requiring fail-safe performance, such as life-support or safety
# devices or systems, Class III medical devices, nuclear facilities, applications
# related to the deployment of airbags, or any other applications that could lead
# to death, personal injury, or severe property or environmental damage
# (individually and collectively, "Critical Applications"). Customer assumes the
# sole risk and liability of any use of Xilinx products in Critical Applications,
# subject only to applicable laws and regulations governing limitations on product
# liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
#
#------------------------------------------------------------------------------------------
#
# Constraints for 'kc705_kcpsm6_icap.vhd'.
#
# KC705 Board (www.xilinx.com) Rev 1.1
#
# XC7K325T-1FFG900 Device
#
# Ken Chapman - Xilinx Ltd
#
# 15th August 2014
#
#
# DEVICE
# ------
#
# On the KC705 board, bank 0 and the CFGBVS pin are connected to a 2.5v supply.
#
# Configuration voltage supplied to bank 0
# Specified as an actual voltage value
set_property CONFIG_VOLTAGE 2.5 [current_design]
#
# Configuration Bank Voltage Selection (CFGBVS)
# Specified as VCCO (as in this case) or GND
set_property CFGBVS VCCO [current_design]
#
#
# Essential Bits File Generation
# ------------------------------
#
# This will make Vivado generate an Essential Bits Data (EBD) file and an
# Essential Bits Configuration (EBC) file.
#
set_property bitstream.seu.essentialbits yes [current_design]
#
#
# TIMING
# ------
#
# 200MHz clock from oscillator on KC705 board
#
create_clock -period 5 -name clk200 -waveform {0 2.5} -add [get_ports clk200_p]
#
# 100MHz internal clock
#
create_clock -period 10 -name clk -waveform {0 5.0} -add [get_nets clk]
#
# Signals that appear to be clocks and need to be given a definition to prevent Vivado warnings
#
create_clock -period 100 -name JTAG_Loader_DRCK -waveform {0 10} -add [get_pins program_rom/instantiate_loader.jtag_loader_6_inst/jtag_loader_gen.BSCAN_7SERIES_gen.BSCAN_BLOCK_inst/DRCK]
create_clock -period 1000 -name JTAG_Loader_UPDATE -waveform {0 80} -add [get_pins program_rom/instantiate_loader.jtag_loader_6_inst/jtag_loader_gen.BSCAN_7SERIES_gen.BSCAN_BLOCK_inst/UPDATE]
#
# Tell Vivado to treat all clocks as asynchronous to again prevent unnecessary constraints and warnings.
#
set_clock_groups -name my_async_clocks -asynchronous -group [get_clocks clk200] -group [get_clocks clk] -group [get_clocks JTAG_Loader_DRCK] -group [get_clocks JTAG_Loader_UPDATE]
#
#
#
# I/O timing is not critical but constraints prevent unnecessary constraints and Vivado warnings.
# Unfortunately Vivado is still reporting 'partial input delay' and 'partial output delay' warnings.
#
#
set_max_delay 50 -from [get_ports uart_rx] -to [get_clocks clk200] -quiet -datapath_only
set_min_delay 0 -from [get_ports uart_rx] -to [get_clocks clk200] -quiet
set_max_delay 50 -from [get_ports cpu_rst] -to [get_clocks clk200] -quiet -datapath_only
set_min_delay 0 -from [get_ports cpu_rst] -to [get_clocks clk200] -quiet
#
set_max_delay 50 -from [get_clocks clk] -to [get_ports uart_tx] -quiet -datapath_only
set_min_delay 0 -from [get_clocks clk] -to [get_ports uart_tx] -quiet
set_max_delay 50 -from [get_clocks clk] -to [get_ports led[0]] -quiet -datapath_only
set_min_delay 0 -from [get_clocks clk] -to [get_ports led[0]] -quiet
set_max_delay 50 -from [get_clocks clk] -to [get_ports led[1]] -quiet -datapath_only
set_min_delay 0 -from [get_clocks clk] -to [get_ports led[1]] -quiet
set_max_delay 50 -from [get_clocks clk] -to [get_ports led[2]] -quiet -datapath_only
set_min_delay 0 -from [get_clocks clk] -to [get_ports led[2]] -quiet
set_max_delay 50 -from [get_clocks clk] -to [get_ports led[3]] -quiet -datapath_only
set_min_delay 0 -from [get_clocks clk] -to [get_ports led[3]] -quiet
set_max_delay 50 -from [get_clocks clk] -to [get_ports led[4]] -quiet -datapath_only
set_min_delay 0 -from [get_clocks clk] -to [get_ports led[4]] -quiet
set_max_delay 50 -from [get_clocks clk] -to [get_ports led[5]] -quiet -datapath_only
set_min_delay 0 -from [get_clocks clk] -to [get_ports led[5]] -quiet
set_max_delay 50 -from [get_clocks clk] -to [get_ports led[6]] -quiet -datapath_only
set_min_delay 0 -from [get_clocks clk] -to [get_ports led[6]] -quiet
set_max_delay 50 -from [get_clocks clk] -to [get_ports led[7]] -quiet -datapath_only
set_min_delay 0 -from [get_clocks clk] -to [get_ports led[7]] -quiet
#
#
#
#
#
# SPECIAL PLACEMENTS
# ------------------
#
# Force ICAPE2 to the required (top) site in the device.
#
set_property LOC ICAP_X0Y1 [get_cells icap]
#
#
# Force FRAME_ECCE2 to the required (only) site in the device.
#
set_property LOC FRAME_ECC_X0Y0 [get_cells frame_ecc]
#
#
#
# DEFINE I/O PINS
# ---------------
#
#
# 200MHz Differential Clock
# -------------------------
#
set_property PACKAGE_PIN AD12 [get_ports clk200_p]
set_property IOSTANDARD DIFF_SSTL15 [get_ports clk200_p]
#
set_property PACKAGE_PIN AD11 [get_ports clk200_n]
set_property IOSTANDARD DIFF_SSTL15 [get_ports clk200_n]
#
#
# USB-UART
# --------
#
set_property PACKAGE_PIN M19 [get_ports uart_rx]
set_property IOSTANDARD LVCMOS25 [get_ports uart_rx]
#
set_property PACKAGE_PIN K24 [get_ports uart_tx]
set_property IOSTANDARD LVCMOS25 [get_ports uart_tx]
set_property SLEW SLOW [get_ports uart_tx]
set_property DRIVE 4 [get_ports uart_tx]
#
#
# CPU_RST press switch (SW7)
# --------------------------
#
# This input is not used by this design but the constraints have been provided for
# additional reference.
#
# Active High
#
set_property PACKAGE_PIN AB7 [get_ports cpu_rst]
set_property IOSTANDARD LVCMOS15 [get_ports cpu_rst]
#
#
# GPIO LEDs
# ---------
#
# Active High
# LED[3:0] are in a 1.5v bank
# LED[7:4] are in banks supplied with Vadj which makes it tricky!
# Default for Vadj is 2.5v.
#
#
set_property PACKAGE_PIN AB8 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS15 [get_ports {led[0]}]
set_property SLEW SLOW [get_ports {led[0]}]
set_property DRIVE 4 [get_ports {led[0]}]
#
set_property PACKAGE_PIN AA8 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS15 [get_ports {led[1]}]
set_property SLEW SLOW [get_ports {led[1]}]
set_property DRIVE 4 [get_ports {led[1]}]
#
set_property PACKAGE_PIN AC9 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS15 [get_ports {led[2]}]
set_property SLEW SLOW [get_ports {led[2]}]
set_property DRIVE 4 [get_ports {led[2]}]
#
set_property PACKAGE_PIN AB9 [get_ports {led[3]}]
set_property IOSTANDARD LVCMOS15 [get_ports {led[3]}]
set_property SLEW SLOW [get_ports {led[3]}]
set_property DRIVE 4 [get_ports {led[3]}]
#
set_property PACKAGE_PIN AE26 [get_ports {led[4]}]
set_property IOSTANDARD LVCMOS25 [get_ports {led[4]}]
set_property SLEW SLOW [get_ports {led[4]}]
set_property DRIVE 4 [get_ports {led[4]}]
#
set_property PACKAGE_PIN G19 [get_ports {led[5]}]
set_property IOSTANDARD LVCMOS25 [get_ports {led[5]}]
set_property SLEW SLOW [get_ports {led[5]}]
set_property DRIVE 4 [get_ports {led[5]}]
#
set_property PACKAGE_PIN E18 [get_ports {led[6]}]
set_property IOSTANDARD LVCMOS25 [get_ports {led[6]}]
set_property SLEW SLOW [get_ports {led[6]}]
set_property DRIVE 4 [get_ports {led[6]}]
#
set_property PACKAGE_PIN F16 [get_ports {led[7]}]
set_property IOSTANDARD LVCMOS25 [get_ports {led[7]}]
set_property SLEW SLOW [get_ports {led[7]}]
set_property DRIVE 4 [get_ports {led[7]}]
#
#
#------------------------------------------------------------------------------------------
# End of File
#------------------------------------------------------------------------------------------
#

View File

@ -0,0 +1,451 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2014, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; PicoBlaze Reference Design - Line Editor.
;
;
; Ken Chapman - Xilinx Ltd
;
; 18th August 2014 - Initial version.
;
;
; The primary routine provided in this file enables the user of the terminal connected
; to the UART communication link to enter a line consisting of multiple characters. Simple
; editing of the characters on a line can be performed using the back space key prior to
; line entry being terminated by a carriage return (CR). The 'read_line' routine has been
; developed to work with PicoTerm provided in the PicoTerm package. If you require further
; information about PicoTerm then please refer to 'PicoTerm_README.txt' which describes
; basic usage as well as the control characters and control sequences that can be used
; with it. The 'read_line' routine will probably work with other terminal applications but
; the ability to edit a line does depend of the way a terminal reacts to the back space
; character.
;
; The line if characters entered are stored in scratch pad memory. The amount of scratch
; pad memory defined for the line buffer defines the maximum number of characters allowed
; on a line.
;
; IMPORTANT - Two CONSTANT directives are described and defined below and these must
; be set to allocate the area of scratch pad memory used to store the
; characters forming a line. All other code must respect the purpose of
; these memory locations.
;
; The other routines provided in this file can be used to analyse or modify the characters
; of a line stored in the scratch pad memory line buffer. For example, there are routines
; to report the number of characters on the line, display the line and convert an ASCII
; hexadecimal value of up to 8-digits into a 32-bit value.
;
;
; NOTE - This is not a standalone PSM file. This file should be included in
; an application PSM file from which these routines are then called.
;
; INCLUDE "line_input_and_editing.psm"
;
;
; NOTE - The code in this file uses UART communication routines that are defined and
; provided in 'PicoTerm_routines.psm'. Therefore that file should also be
; included in an application PSM file (or copy the routines within it).
;
; Obviously communication with PicoTerm requires the UART macros to be connected to
; KCPSM6 and for PicoTerm to be connected and active.
;
;
;------------------------------------------------------------------------------------------
; Scratch Pad Memory
;------------------------------------------------------------------------------------------
;
; The CONSTANT directives below define the allocation of scratch pad memory locations
; used to store a line of characters terminated by a carriage return (CR).
;
; The difference between 'line_buffer_start' and 'line_buffer_end' defines the maximum
; number of characters that can be entered on the line.
;
; It vital that the memory location specified for 'line_buffer_end' is greater than the
; memory location specified for 'line_buffer_start'. This should feel obvious and natural
; but it is worth double checking your definitions because a failure to do this will result
; in a buffer that will wrap round from the last memory location to the first memory
; location (i.e. probably occupying every memory location except that the locations you
; that you originally intended it to!).
;
; A buffer to store up to 32 characters (including a terminating carriage return).
;
CONSTANT line_buffer_start, E0
CONSTANT line_buffer_end, FF
;
;
;------------------------------------------------------------------------------------------
; Read one 'line' from the keyboard
;------------------------------------------------------------------------------------------
;
; This routine will allow the user to enter characters at the keyboard until terminated by
; a carriage return (CR). The backspace (BS) key will be recognised and facilitate some
; simple editing of characters on the line prior to submission.
;
; If the user enters enough characters to fill the line buffer the user will be unable to
; enter any more characters. The back space key can be used to delete characters thereby
; creating space in the line buffer and enabling new characters to be entered again. CR can
; also be used to submit a line that fills the buffer.
;
; Note that the line buffer location and size is defined by the 'line_buffer_start' and
; 'line_buffer_end' constants. The line buffer will always store the carriage return (CR)
; to indicate the end of the actual line stored in the buffer (i.e. lines will often be
; shorter than the maximum supported).
;
;
; Registers used s0, s1, s2 and s5.
;
read_line: LOAD s2, line_buffer_start ;memory pointer
;
read_line_loop: CALL UART_RX ;wait for a key to be entered
JUMP Z, read_line_loop ;character returned in s5 if no timeout
;
COMPARE s5, BS ;test for back space
JUMP Z, delete_character
;
STORE s5, (s2) ;store character
CALL UART_TX ;echo character to screen (including CR)
;
COMPARE s5, CR ;test for carriage return to end routine
RETURN Z
;
; Increment memory pointer for next character.
;
; If the buffer is already full then delete the last character entered from the screen
; and do not increment the memory pointer. The user may see the flickering of the last
; character entered but this acts as a visual indication of reaching the line limit.
;
COMPARE s2, line_buffer_end
JUMP Z, line_buffer_full
ADD s2, 01 ;increment pointer
JUMP read_line_loop
;
line_buffer_full: LOAD s5, BS ;delete last character on screen
CALL UART_TX
JUMP read_line_loop
;
; When 'BS' is entered then delete the previous character on the display and decrement the
; pointer. The buffer contents are not changed but the pointer and eventual location of a
; carriage return character will identify which characters are valid when the line is
; interpreted. If the pointer is already at the start of the buffer then the pointer
; remains the same and there is no need to send any characters to the screen (in this
; situation there is not even a character on the display to delete).
;
delete_character: COMPARE s2, line_buffer_start ;test for start of buffer
JUMP Z, read_line_loop
CALL UART_TX ;BS deletes previous character
SUB s2, 01 ;decrement pointer
JUMP read_line_loop
;
;
;------------------------------------------------------------------------------------------
; Display the line currently stored in scratch pad memory line buffer
;------------------------------------------------------------------------------------------
;
; This routine will display all the characters held in the line buffer up to and including
; the carriage return (CR).
;
; Note - Do not call this routine before the 'read_line' routine has been used at least
; once. This routine requires a carriage return (CR) to be encountered!
;
; Registers used s0, s1 and s5.
;
send_line: LOAD s1, line_buffer_start ;memory pointer
;
send_line_loop: FETCH s5, (s1) ;fetch character
CALL UART_TX ;display character (including CR)
;
COMPARE s5, CR ;test for carriage return to end routine
RETURN Z
;
ADD s1, 01 ;increment pointer
JUMP send_line_loop
;
;
;------------------------------------------------------------------------------------------
; Determine the length of the 'line' held in the memory buffer
;------------------------------------------------------------------------------------------
;
; This routine will return the number of characters held in the line buffer in register s2.
; The character count does not include the carriage return signifying the end of the line.
; An empty line will have the carriage return in the first location and therefore s2=00.
;
; Note - Do not call this routine before the 'read_line' routine has been used at least
; once. This routine requires a carriage return (CR) to be encountered!
;
; Hint - On return, 's1' will point to the location of the carriage return (CR) which
; can also be useful to know.
;
; Registers used s0, s1 and s2.
;
line_length: LOAD s1, line_buffer_start ;memory pointer
LOAD s2, 00 ;clear counter
;
line_length_loop: FETCH s0, (s1) ;read character
COMPARE s0, CR ;test for end of line
RETURN Z
ADD s1, 01 ;increment pointer
ADD s2, 01 ;increment counter
JUMP line_length_loop
;
;
;------------------------------------------------------------------------------------------
; Convert characters of the 'line' held in the memory buffer to upper case
;------------------------------------------------------------------------------------------
;
; This routine will scan through the line converting any lower case characters to upper
; case.
;
; Note - Do not call this routine before the 'read_line' routine has been used at least
; once. This routine requires a carriage return (CR) to be encountered!
;
; Hint - On return, 's1' will point to the location of the carriage return (CR) which
; can also be useful to know.
;
; Registers used s0 and s1
;
line_upper_case: LOAD s1, line_buffer_start ;memory pointer
;
line_upper_case_loop: FETCH s0, (s1) ;read character
COMPARE s0, CR ;test for end of line
RETURN Z
;
COMPARE s0, "a" ;eliminate character codes below 'a' (61 hex)
JUMP C, next_luc_char
COMPARE s0, 7B ;eliminate character codes above 'z' (7A hex)
JUMP NC, next_luc_char
AND s0, 11011111'b ;force bit5 Low to convert to upper case
STORE s0, (s1) ;store modified character
;
next_luc_char: ADD s1, 01 ;increment pointer
JUMP line_upper_case_loop
;
;
;------------------------------------------------------------------------------------------
; Convert ASCII Hexadecimal 'line' to a 32-bit Value
;------------------------------------------------------------------------------------------
;
; This routine will interpret a line containing ASCII hexadecimal characters into a 32-bit
; value which is returned in register set [sF,sE,sD,sC]. The line can contain any number
; of characters up to a maximum of 8 hexadecimal digits which is consistent with a 32-bit
; value.
;
; Valid hexadecimal characters are 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E and F but lower case
; characters are also accepted and automatically converted to upper case characters in
; the line buffer.
;
; If the line is empty or contains more than 8 characters the routine will return with
; the carry flag set. Likewise, if the line contains any non-hexadecimal characters the
; routine will return with the carry flag set to indicate an error.
;
; When a valid hexadecimal value (e.g. anything in the range '0' to 'FFFFFFFF') is
; provided in the line buffer then the 32-bit value is returned in register set
; [sF,sE,sD,sC] with the carry flag cleared.
;
; Note - Do not call this routine before the 'read_line' routine has been used at least
; once. This routine requires a carriage return (CR) to be encountered!
;
; Registers used s0, s1, s2, sC, sD, sE and sF
;
;
line_32bit_hex: CALL line_length ;number of characters in s2
;
; There must be between 1 and 8 characters in the line buffer.
; Adding 247 to the character count in s2 will set the carry flag if there are more than
; 8 characters. Adding another 9 will restore the original value of s2 but will also
; ensure that the carry flag is set so that a test for s2=00 will also abort with C=1.
;
ADD s2, 247'd ;test for >8 characters
RETURN C ;abort with carry flag set
ADD s2, 9'd ;test for empty line
RETURN Z ;abort with carry flag set
;
CALL line_upper_case ;Make sure characters are upper case ready to be converted
;
; Scan the line from left to right converting each hex digit to its corresponding 4-bit
; value. Working from left to right means that the first digit converted defines the most
; significant bits and the last digit converted defined the least significant bits. So as
; each digit is converted its 4-bits are shifted into the least significant bits of
; [sF,sE,sD,sC]. If less than 8-digits are specified the most significant bits of the
; returned value will be zero.
;
LOAD sC, 00 ;Clear 32-bit result
LOAD sD, 00 ; This ensures that MSBs are zero when
LOAD sE, 00 ; less than 8 hex digits on line
LOAD sF, 00
;
LOAD s1, line_buffer_start ;memory pointer
;
l32b_convert_loop: FETCH s0, (s1) ;read character
COMPARE s0, CR ;test for end of line
RETURN Z ;conversion complete (carry flag is clear)
;
; Convert the ASCII character in 's0' to an equivalent numerical 4-bit value.
;
; Characters ASCII codes (hex) Value
; 0 - 9 30 - 39 00 - 09
; A - F 41 - 46 0A - 0F
;
; If any character is not valid for hex then return with carry flag set.
;
ADD s0, B9 ;test for above ASCII code 46 hex ('F')
RETURN C ; and fail if character is!
SUB s0, E9 ;normalise 0 to 9 with A-F in range 11 to 16 hex
RETURN C ; and fail for character below code 30 hex ('0')
SUB s0, 11 ;isolate A-F down to 00 to 05 hex
JUMP NC, Hex_letter
ADD s0, 07 ;test for above ASCII code 39 hex ('9')
RETURN C ; and fail if character is!
SUB s0, F6 ;convert to range 00 to 09
JUMP l32b_shift
Hex_letter: ADD s0, 0A ;convert A-F to value in range 0A to 0F
;
; Shift 4-bit value in 's0' into the least significant bits of [sF,sE,sD,sC].
;
l32b_shift: LOAD s2, 00001000'b ;bit mask and one-hot counter
l32b_shift_loop: TEST s0, s2 ;copy bit to carry flag
SLA sC ;shift 32-bit value left injecting carry into LSB
SLA sD
SLA sE
SLA sF
SR0 s2 ;shift mask to next bit
JUMP NZ, l32b_shift_loop
;
ADD s1, 01 ;increment pointer
JUMP l32b_convert_loop
;
;
;------------------------------------------------------------------------------------------
; Convert ASCII Decimal 'line' to a 16-bit Value
;------------------------------------------------------------------------------------------
;
; This routine will interpret a line containing ASCII decimal characters into a 16-bit
; value which is returned in register set [s9,s8]. The line can contain any number
; of characters up to a maximum of 5 decimal digits which is consistent with a 16-bit
; value.
;
; Valid decimal characters are 0,1,2,3,4,5,6,7,8 and 9. If the line contains any
; non-decimal characters the routine will return with the carry flag set to indicate an
; error. Likewise, if the line is empty or contains more than 5 characters the routine
; will return with the carry flag set.
;
; When a valid decimal value (e.g. anything in the range '0' to '65535') is provided in
; the line buffer then the 16-bit value is returned in register set [s9,s8] with the
; carry flag cleared.
;
; Note - Do not call this routine before the 'read_line' routine has been used at least
; once. This routine requires a carriage return (CR) to be encountered!
;
; Registers used s0, s1, s2, s3, s4, s8, s9
;
; 'line_length' determines the number of characters in the line buffer and returns that
; count in register s3. Register s2 is also pointing to the carriage return that
; terminates the line.
;
decimal_line: CALL line_length ;number of characters in s2 (and s1 points to CR)
;
; There must be between 1 and 5 characters in the line buffer.
; Adding 250 to the character count in s2 will set the carry flag if there are more than
; 5 characters. Adding another 6 will restore the original value of s2 but will also
; ensure that the carry flag is set so that a test for s2=00 will also abort with C=1.
;
ADD s2, 250'd ;test for >5 characters
RETURN C ;abort with carry flag set
ADD s2, 6'd ;test for empty line
RETURN Z ;abort with carry flag set
;
LOAD s8, 00 ;clear [s9,s8] ready for conversion result
LOAD s9, 00
;
; [s5,s4] will hold a value consistent with the decimal digit being processed.
; Processing starts with the least significant digit which has a weighting of 1.
;
LOAD s3, 01
LOAD s4, 00
;
decimal_line_loop: SUB s1, 1'd ;decrement pointer
FETCH s0, (s1) ;read character
;
; ASCII character should be in the range 30 to 39 hex.
; Adding C6 to the ASCII code in s0 will set the carry flag if the code is >39 hex.
; Then subtracting F6 hex will convert the ASCII code to an absolute value in the
; range 00 to 09 hex but will also set the carry flag if the original ASCII code
; was <30 hex.
;
ADD s0, C6 ;test for >39 hex
RETURN C ;abort with carry flag set
SUB s0, F6 ;convert to value
RETURN C ;abort with carry flag set
;
; Apply the digit value and digit weighting to the conversion result
;
digit_convert: SUB s0, 1'd ;digit conversion complete?
JUMP C, next_decimal_weight
ADD s8, s3 ;add digit weight to conversion result
ADDCY s9, s4
RETURN C ;abort with carry flag set if >65,536 (FFFF)
JUMP digit_convert
;
; Multiply current digit weight by 10.
;
next_decimal_weight: LOAD s0, s3 ;copy [s4,s3] to [s1,s0]
LOAD s1, s4
SL0 s3 ;shift [s4,s3] left twice to achieve 4x
SLA s4
SL0 s3
SLA s4
ADD s3, s0 ;add [s1,s0] to achieve 5x
ADDCY s4, s1
SL0 s3 ;shift [s4,s3] left to achieve 10x
SLA s4
;
SUB s2, 1'd ;decrement digits remaining to be converted
RETURN Z ;conversion complete (carry flag is clear)
;
JUMP decimal_line_loop
;
;
;------------------------------------------------------------------------------------------
; End of 'line_input_and_editing.psm'
;------------------------------------------------------------------------------------------
;

View File

@ -0,0 +1,292 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2014, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
--
-- Single Port RAM
-- 4096 x 8-bits
-- One RAMB36E1 primitive
--
-- Ken Chapman
-- Xilinx UK
-- 24th July 2014
--
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
--
entity ram_4096x8 is
Port ( address : in std_logic_vector(11 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
we : in std_logic;
clk : in std_logic);
end ram_4096x8;
--
architecture low_level_definition of ram_4096x8 is
--
signal address_a : std_logic_vector(15 downto 0);
signal data_in_a : std_logic_vector(35 downto 0);
signal we_a : std_logic_vector(3 downto 0);
signal data_out_a : std_logic_vector(35 downto 0);
signal address_b : std_logic_vector(15 downto 0);
signal data_in_b : std_logic_vector(35 downto 0);
signal data_out_b : std_logic_vector(35 downto 0);
--
begin
--
address_a <= '1' & address(11 downto 0) & "111";
data_in_a <= "000" & data_out_a(32) & "000000000000000000000000" & data_in;
we_a <= we & we & we & we;
data_out <= data_out_a(7 downto 0);
--
address_b <= "1111111111111111";
data_in_b <= "000" & data_out_b(32) & "000000000000000000000000" & data_out_b(7 downto 0);
--
ram_4096x8: RAMB36E1
generic map ( READ_WIDTH_A => 9,
WRITE_WIDTH_A => 9,
DOA_REG => 0,
INIT_A => X"000000000",
RSTREG_PRIORITY_A => "REGCE",
SRVAL_A => X"000000000",
WRITE_MODE_A => "WRITE_FIRST",
READ_WIDTH_B => 9,
WRITE_WIDTH_B => 9,
DOB_REG => 0,
INIT_B => X"000000000",
RSTREG_PRIORITY_B => "REGCE",
SRVAL_B => X"000000000",
WRITE_MODE_B => "WRITE_FIRST",
INIT_FILE => "NONE",
SIM_COLLISION_CHECK => "ALL",
RAM_MODE => "TDP",
RDADDR_COLLISION_HWCONFIG => "DELAYED_WRITE",
EN_ECC_READ => FALSE,
EN_ECC_WRITE => FALSE,
RAM_EXTENSION_A => "NONE",
RAM_EXTENSION_B => "NONE",
SIM_DEVICE => "7SERIES",
INIT_00 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_40 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_41 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_42 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_43 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_44 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_45 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_46 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_47 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_48 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_49 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_4A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_4B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_4C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_4D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_4E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_4F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_50 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_51 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_52 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_53 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_54 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_55 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_56 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_57 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_58 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_59 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_5A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_5B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_5C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_5D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_5E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_5F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_60 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_61 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_62 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_63 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_64 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_65 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_66 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_67 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_68 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_69 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_6A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_6B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_6C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_6D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_6E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_6F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_70 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_71 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_72 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_73 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_74 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_75 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_76 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_77 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_78 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_79 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_7A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_7B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_7C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_7D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_7E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_7F => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_00 => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_08 => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_09 => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_0A => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_0B => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_0C => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_0D => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_0E => X"0000000000000000000000000000000000000000000000000000000000000000",
INITP_0F => X"0000000000000000000000000000000000000000000000000000000000000000")
port map( ADDRARDADDR => address_a,
ENARDEN => '1',
CLKARDCLK => clk,
DOADO => data_out_a(31 downto 0),
DOPADOP => data_out_a(35 downto 32),
DIADI => data_in_a(31 downto 0),
DIPADIP => data_in_a(35 downto 32),
WEA => we_a,
REGCEAREGCE => '0',
RSTRAMARSTRAM => '0',
RSTREGARSTREG => '0',
ADDRBWRADDR => address_b,
ENBWREN => '0',
CLKBWRCLK => '0',
DOBDO => data_out_b(31 downto 0),
DOPBDOP => data_out_b(35 downto 32),
DIBDI => data_in_b(31 downto 0),
DIPBDIP => data_in_b(35 downto 32),
WEBWE => "00000000",
REGCEB => '0',
RSTRAMB => '0',
RSTREGB => '0',
CASCADEINA => '0',
CASCADEINB => '0',
INJECTDBITERR => '0',
INJECTSBITERR => '0');
--
--
end low_level_definition;
--
------------------------------------------------------------------------------------
--
-- END OF FILE ram_4096x8.vhd
--
------------------------------------------------------------------------------------

View File

@ -0,0 +1,425 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2012-2013, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; PicoBlaze Reference Design.
;
;
; Ken Chapman - Xilinx Ltd
;
; 25th September 2012 - Initial version
; 23rd January 2013 - Adjustments to commensts only
;
; This file contains routines to implement classic 4-wire SPI communication with a
; Micron/Numonyx N25Q128 device. A limited number of the N25Q128 device instructions
; are covered to facilitate typical flash memory operations and to act as reference
; code for future additions if required. Whilst presented as being specifically for
; the N25Q128 device, SPI Flash memory devices have much in common particularly when
; reading memory contents. It is the internal organisation of the flash memory, and
; operations related to erasing and writing that tend to vary so always refer to the
; manufacturers data sheet.
;
; NOTE - This is not a standalone PSM file. This file should be included in
; an application PSM file from which these routines are then called.
;
; INCLUDE "N25Q128_SPI_routines.psm"
;
;
; IMPORTANT - This file contains routines to implement the SPI signaling used in
; the communication with the N25Q128 device so the CONSTANT directives
; defined below must be set to correspond with your I/O port and scratch
; pad memory assignments.
;
;
;------------------------------------------------------------------------------------------
; Hardware Constants
;------------------------------------------------------------------------------------------
;
; The hardware defines a classic 4-wire SPI interface with the N25Q128 device.
;
; spi_clk Clock from FPGA (KCPSM6) to SPI Flash
; spi_cs_b Chip Select from FPGA (KCPSM6) to SPI Flash
; spi_mosi Data from FPGA (KCPSM6) to SPI Flash
; spi_miso Data from SPI Flash to FPGA (KCPSM6)
;
; The three output signals are driven directly by a single KCPSM6 output and the input
; signal is read by a single input port. The CONSTANT directives below define the input
; port and output port assigned for SPI communication and should match the definition
; within the hardware.
;
CONSTANT SPI_output_port, 04 ; Write controls and data to SPI Flash Memory
CONSTANT SPI_data_in_port, 03 ; Read serial data from SPI Flash
;
; The following CONSTANT directives identify which bits of each 8-bit port are
; assigned to each signal. These constants and the hardware should NOT be modified
; unless these is a compelling reason to do so. In particular, the serial data input
; and serial data output have both been assigned to Bit7 as this simplifies the PSM
; code when implementing the most significant bit (MSB) protocol of the serial
; communication.
;
CONSTANT spi_clk, 00000001'b ; spi_clk - bit0 (SPI_output_port)
CONSTANT spi_cs_b, 00000010'b ; spi_cs_b - bit1 (SPI_output_port)
CONSTANT spi_mosi, 10000000'b ; spi_mosi - bit7 (SPI_output_port)
CONSTANT spi_miso, 10000000'b ; spi_miso - bit7 (SPI_data_in_port)
;
;
;--------------------------------------------------------------------------------------
; Routine to Read the ID from SPI FLASH memory (N25Q128)
;--------------------------------------------------------------------------------------
;
; This routine transmits the 'RDID' instruction (9F hex) to the flash memory and then
; receives and returns the first 3 bytes of the response in registers [s9,s8,s7]. the
; expected response is shown below.
;
; s9 = Manufacturer Identification = 20 hex
; s8 = Memory Type = BA hex
; s7 = Memory Capacity = 18 hex
;
; Note that the full response to an 'RDID' is 20-bytes. In this case only the
; first 3 bytes are taken because these should be the same for any N25Q128 device.
; The remaining bytes can contain be values uniquely defined by a customer and
; factory programmed. If these bytes are important to your application then please
; adjust this routine appropriately.
;
read_spi_flash_ID: CALL SPI_disable ;ensure known state of bus and s0 register
LOAD s2, 9F ;RDID instruction
CALL SPI_FLASH_tx_rx ;transmit instruction
CALL SPI_FLASH_tx_rx ;receive Manufacturer ID
LOAD s9, s2
CALL SPI_FLASH_tx_rx ;receive Memory Type
LOAD s8, s2
CALL SPI_FLASH_tx_rx ;receive Memory Capacity
LOAD s7, s2
JUMP SPI_disable ;terminate transaction (includes return)
;
;
;--------------------------------------------------------------------------------------
; Routine to Read 1-Byte from SPI FLASH memory (N25Q128)
;--------------------------------------------------------------------------------------
;
; This routine transmits the 'READ' instruction (03 hex) to the flash memory followed
; by a 24-bit address supplied in register set [s9,s8,s7].. Then one byte of data is
; received and returned in register s2.
;
read_spi_byte: CALL SPI_disable ;ensure known state of bus and s0 register
LOAD s2, 03 ;READ instruction
CALL SPI_FLASH_tx_rx ;transmit instruction
LOAD s2, s9 ;Transmit 24-bit address
CALL SPI_FLASH_tx_rx
LOAD s2, s8
CALL SPI_FLASH_tx_rx
LOAD s2, s7
CALL SPI_FLASH_tx_rx
CALL SPI_FLASH_tx_rx ;read data byte **
JUMP SPI_disable ;terminate transaction (includes return)
;
; ** Note that after reading the first byte, it is actually possible to continue
; reading bytes of data from successive addresses until the device is disabled. This
; is a more efficient way of reading large amounts of sequential data but clearly a
; different arrangement to this routine would be required mainly to handle the
; additional data.
;
;
;--------------------------------------------------------------------------------------
; Routine to Write 1-Byte to SPI FLASH memory (N25Q128)
;--------------------------------------------------------------------------------------
;
; This routine writes one byte of information provided in register 's2' to the 24-bit
; address supplied in register set [s9,s8,s7]. This procedure involves setting the
; Write Enable Latch (WEL) bit before transmitting the 'PP' instruction (02 hex)
; followed by the 24-bit address and the data byte to be written. Finally the Write
; Enable Latch (WEL) is reset to return the Flash to normal operation.
;
; Note that when writing to Flash memory, each bit can only be changed from '1' to '0'
; and therefore it is normal practice to only write to previously erased locations
; that contain FF hex.
;
; Programming or writing can take up to 5ms to complete so this procedure also reads
; and tests the N25Q128 status resister to determine when the operation has completed.
;
;
write_spi_byte: LOAD sD, s2 ; Preserve data to be written
;
CALL SPI_disable ;ensure known state of bus and s0 register
CALL set_spi_flash_WREN ;set write enable latch
;
LOAD s2, 02 ;PP instruction
CALL SPI_FLASH_tx_rx ;transmit instruction
LOAD s2, s9 ;Transmit 24-bit address
CALL SPI_FLASH_tx_rx
LOAD s2, s8
CALL SPI_FLASH_tx_rx
LOAD s2, s7
CALL SPI_FLASH_tx_rx
LOAD s2, sD ;Transmit data byte **
CALL SPI_FLASH_tx_rx
CALL SPI_disable ;terminate PP transaction
;
page_prog_wait: CALL read_spi_flash_status ;read N25Q128 status
TEST s2, 00000001'b ;test WIP bit until finished
JUMP NZ, page_prog_wait
;
CALL reset_spi_flash_WREN ;clear write enable latch
RETURN
;
; ** Note that after writing the first byte, it is possible to continue writing
; bytes of data to successive addresses providing that they are within the same PAGE
; (e.g. write 256 bytes of data starting at address 'sspp00' and finishing at
; address 'ssppFF'). This is a more efficient way of writing large amounts of data
; especially as each program cycle takes up to 5ms to complete. Clearly a different
; arrangement to this routine would be required mainly to handle the additional data.
;
;
;--------------------------------------------------------------------------------------
; Routine to Erase One SECTOR (N25Q128)
;--------------------------------------------------------------------------------------
;
; The N25Q128 memory is 16M-bytes and organised into 256 Sectors. Each Sector contains
; 256 Pages which in turn contain 256 Bytes. So in terms of the 24-bit address...
;
; address[23:16] = Sector (Register 's9')
; address[15:9] = Page (Register 's8')
; address[7:0] = Byte (Register 's7')
;
; A Sector is generally the smallest zone of memory that can be erased (all bytes
; become FF hex) and therefore this routine will erase 65,536 bytes (64KB).
;
; This routine will erase the sector in which the address supplied in register set
; [s9,s8,s7] is located. In other words, the contents of 's9' define the Sector.
;
; The sector erase procedure involves setting the Write Enable Latch (WEL) bit
; before transmitting the 'SE' instruction (D8 hex) followed by the 24-bit address.
; In this case the Write Enable Latch (WEL) is automatically reset.
;
; Erasing a Sector can take up to 3 seconds (typically 0.7 seconds) to complete so this
; procedure also reads and tests the N25Q128 status resister to determine when the
; operation has completed.
;
;
erase_spi_sector: CALL SPI_disable ;ensure known state of bus and s0 register
CALL set_spi_flash_WREN ;set write enable latch
;
LOAD s2, D8 ;SE instruction
CALL SPI_FLASH_tx_rx ;transmit instruction
LOAD s2, s9 ;Transmit 24-bit address
CALL SPI_FLASH_tx_rx
LOAD s2, s8
CALL SPI_FLASH_tx_rx
LOAD s2, s7
CALL SPI_FLASH_tx_rx
CALL SPI_disable ;terminate SE transaction
;
sector_erase_wait: CALL read_spi_flash_status ;read N25Q128 status
TEST s2, 00000001'b ;test WIP bit until finished
JUMP NZ, sector_erase_wait
RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to Initialise the SPI bus
;--------------------------------------------------------------------------------------
;
; This routine should be used to initialise the SPI bus. It will deselect the SPI Flash
; memory and ensure a known state for the control signals and contents of register 's0'
; used during SPI routines to drive the SPI bus (see 'SPI_disable').
;
; IMPORTANT - The STARTUPE2 primitive provides the path from the 'spi_clk' signal to
; the 'CCLK' pin on the device. However, it takes two rising edges to
; be applied to the USRCCLKO input of the STARTUPE2 primitive before the
; path becomes transparent. For this reason the initialisation routine
; also pulses the 'spi_clk' signal several times as well as ensuring the
; SPI device is disabled.
;
;
SPI_initialise: CALL SPI_disable
LOAD s1, 8'd
SPI_init_burst: CALL SPI_clock_pulse
SUB s1, 1'd
JUMP NZ, SPI_init_burst
RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to Disable the SPI bus
;--------------------------------------------------------------------------------------
;
; This routine is used to disable the SPI bus as part of initialisation or to complete
; (or terminate) an SPI transaction. The routine is also used to ensure the known
; state for the SPI signals and 's0' register before the start of a new transaction.
;
; Content of 's0' and the SPI signals after execution of this routine.
;
; spi_clk = 0 - bit0
; spi_cs_b = 1 - bit1 (disabled)
; spi_mosi = 0 - bit7
;
SPI_disable: LOAD s0, spi_cs_b
OUTPUT s0, SPI_output_port
RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to Transmit and Receive One Byte
;--------------------------------------------------------------------------------------
;
; SPI communication is full duplex meaning that data can be simultaneously transmitted
; and received but in practice this capability is not widely exploited. As such, this
; routine will often be invoked only to transmit a byte or only to receive a byte; the
; fact that it actually always does both at the same time is generally ignored!
;
; This routine will be invoked as part of a complete transaction so the 'SPI_disable'
; routine should have been used at some point prior to this routine being called and
; therefore the states of the SPI signals and 's0' register contents are known. This
; routine will always drive the 'spi_cs_b' signal Low to enable communication to take
; place with the one slave device so there is no requirement to specifically enable
; the N25Q128 device at the start of a transaction but it will be necessary to
; disable it at the end.
;
; The instruction, address or data to be transmitted should be supplied in register
; 's2' and any received information will be returned in 's2' when the routine completes.
;
; The transmission and reception of each bit with an associated 'spi_clk' pulse
; is implemented by 14 instructions that take 28 clock cycles to execute. Hence the
; serial data rate is the KCPSM6 clock frequency divided by 24 (e.g. 3.57 Mbit/s with a
; 100MHz clock ). This is generally a much lower data rate than an SPI device can
; support so no special timing considerations are required. For higher data rates a
; hardware peripheral consisting of a shift register and pulse generator should be
; investigated.
;
; As a KCPSM6 is the SPI master the signal sequence implemented is as follows..
;
; Receive data bit from spi_miso line (Flash transmits on previous falling edge)
; Transmit data bit on spi_mosi line (data set up before rising edge of spi_clk)
; Drive spi_clk transition from low to high (Flash captures data bit)
; Drive spi_clk transition from high to low (Flash outputs next data bit)
;
SPI_FLASH_tx_rx: LOAD s1, 08 ;8-bits to transmit and receive
next_SPI_FLASH_bit: LOAD s0, s2 ;prepare next bit to transmit
AND s0, spi_mosi ;isolates data bit and spi_cs_b = 0
OUTPUT s0, SPI_output_port ;output data bit ready to be used on rising clock edge
INPUT s3, SPI_data_in_port ;read input bit
TEST s3, spi_miso ;carry flag becomes value of received bit
SLA s2 ;shift new data into result and move to next transmit bit
CALL SPI_clock_pulse ;pulse spi_clk High
SUB s1, 01 ;count bits
JUMP NZ, next_SPI_FLASH_bit ;repeat until last bit
RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to Generate One 'spi_clk' Pulse
;--------------------------------------------------------------------------------------
;
; This routine will generate one positive pulse on the 'spi_clk' line.
;
; Register 's0' is used and bit1 and bit7 must previously define the required states
; of 'spi_cs_b' and 'spi_mosi' which will remain unchanged.
;
SPI_clock_pulse: OR s0, spi_clk ;clock High (bit0)
OUTPUT s0, SPI_output_port ;drive clock High
AND s0, ~spi_clk ;clock Low (bit0)
OUTPUT s0, SPI_output_port ;drive clock Low
RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to Read Status Register from SPI FLASH memory (N25Q128)
;--------------------------------------------------------------------------------------
;
; This routine transmits the 'RDSR' instruction (05 hex) to the flash memory and then
; receives the one byte response which is returned in register s2. A summary of the
; status bits are shown below but please see the N25Q128 data sheet for details.
;
; Hint - The 'WIP' bit is generally the bit of most interest.
;
; bit meaning
; 7 SRWD Status Register Write Protect
; 6 BP3 Block protect bit*
; 5 TB Top/bottom bit
; 4 BP2 Block protect bit*
; 3 BP1 Block protect bit*
; 2 BP0 Block protect bit*
; 1 WEL Write Enable Latch Bit (1 = Latch is Set)
; 0 WIP Write In Progress bit (1 = busy)
;
; * Block protect bits are non-volatile (written by WRSR instruction) and
; define the size of memory protected against writes and erase operations.
;
read_spi_flash_status: CALL SPI_disable ;ensure known state of bus and s0 register
LOAD s2, 05 ;RDSR instruction
CALL SPI_FLASH_tx_rx ;transmit instruction
CALL SPI_FLASH_tx_rx ;Receive status register information
JUMP SPI_disable ;end transaction (includes return)
;
;
;--------------------------------------------------------------------------------------
; Routine to Set the Write Enable Latch (N25Q128)
;--------------------------------------------------------------------------------------
;
; This routine transmits the 'WREN' instruction (06 hex) that will set the Write Enable
; Latch (WEL) bit. This bit must be set prior to any program or erase operations.
;
set_spi_flash_WREN: CALL SPI_disable ;ensure known state of bus and s0 register
LOAD s2, 06 ;Set write enable mode instruction
CALL SPI_FLASH_tx_rx ;transmit instruction
JUMP SPI_disable ;terminate transaction (includes return)
;
;
;--------------------------------------------------------------------------------------
; Routine to Reset the Write Enable Latch (N25Q128)
;--------------------------------------------------------------------------------------
;
; This routine transmits the 'WRDI' instruction (04 hex) that will reset (clear) the
; Write Enable Latch (WEL) bit.
;
reset_spi_flash_WREN: CALL SPI_disable ;ensure known state of bus and s0 register
LOAD s2, 04 ;Reset write enable mode instruction
CALL SPI_FLASH_tx_rx ;transmit instruction
JUMP SPI_disable ;terminate transaction (includes return)
;
;
;------------------------------------------------------------------------------------------
; End of 'N25Q128_SPI_routines.psm'
;------------------------------------------------------------------------------------------
;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,113 @@
#
#------------------------------------------------------------------------------------------
# Copyright <20> 2012-2013, Xilinx, Inc.
# This file contains confidential and proprietary information of Xilinx, Inc. and is
# protected under U.S. and international copyright and other intellectual property laws.
#------------------------------------------------------------------------------------------
#
# Disclaimer:
# This disclaimer is not a license and does not grant any rights to the materials
# distributed herewith. Except as otherwise provided in a valid license issued to
# you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
# MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
# DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
# INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
# OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
# (whether in contract or tort, including negligence, or under any other theory
# of liability) for any loss or damage of any kind or nature related to, arising
# under or in connection with these materials, including for any direct, or any
# indirect, special, incidental, or consequential loss or damage (including loss
# of data, profits, goodwill, or any type of loss or damage suffered as a result
# of any action brought by a third party) even if such damage or loss was
# reasonably foreseeable or Xilinx had been advised of the possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-safe, or for use in any
# application requiring fail-safe performance, such as life-support or safety
# devices or systems, Class III medical devices, nuclear facilities, applications
# related to the deployment of airbags, or any other applications that could lead
# to death, personal injury, or severe property or environmental damage
# (individually and collectively, "Critical Applications"). Customer assumes the
# sole risk and liability of any use of Xilinx products in Critical Applications,
# subject only to applicable laws and regulations governing limitations on product
# liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
#
#------------------------------------------------------------------------------------------
#
# Constraints for 'kc705_kcpsm6_spi_flash'.
#
# KC705 Board Rev.D (www.xilinx.com)
#
# XC7K325T-1FFG900 Device
#
# Ken Chapman - Xilinx Ltd
#
# 20th September 2012 - Initial Release.
# 18th March 2013 - Changes to comments only.
#
#
#
#------------------------------------------------------------------------------------------
# Timing Constraints
#------------------------------------------------------------------------------------------
#
#
# Period constraint for 200MHz operation
#
NET "clk200" TNM_NET = "clk200";
TIMESPEC TS_200MHZ_clk = PERIOD "clk200" 5.0ns HIGH 50%;
#
#
# Period constraint for 100MHz operation
#
NET "clk" TNM_NET = "clk";
TIMESPEC TS_100MHZ_clk = PERIOD "clk" 10.0ns HIGH 50%;
#
#
#------------------------------------------------------------------------------------------
# Pin Constraints
#------------------------------------------------------------------------------------------
#
#
# 200MHz Differential Clock (SYSCLK).
#
NET "clk200_p" LOC = "AD12" | IOSTANDARD = DIFF_SSTL15;
NET "clk200_n" LOC = "AD11" | IOSTANDARD = DIFF_SSTL15;
#
#
# USB-UART
#
NET "uart_rx" LOC = "M19" | IOSTANDARD = LVCMOS25;
NET "uart_tx" LOC = "K24" | IOSTANDARD = LVCMOS25 | SLEW = SLOW | DRIVE = 4;
#
#
# CPU_RST press switch is SW7 and active High
#
NET "cpu_rst" LOC = "AB7" | IOSTANDARD = LVCMOS15;
#
#
# SPI Flash N25Q128
#
# Connections for standard serial (X1) communication with the SPI Flash that is also
# available to be used for device configuration. For this reason the design must reuse
# the CCLK, FCS_B, D00 and D01 pins to clock, select and pass serial information to
# and from the SPI Flash device.
#
# Note: CCLK is a dedicated pin accessed via the 'STARTUPE2' primitive
# so this pin (B10) does not require a corresponding constraint.
#
# IMPORTANT: The 'M0' switch on SW13 must be set to '1' so that the 'spi_cs_b' signal
# is routed through to the SPI Flash rather than the parallel Flash. For
# Master SPI configuration the required switch setting is M[2:0]="001".
#
NET "spi_cs_b" LOC = "U19" | IOSTANDARD = LVCMOS25 | SLEW = SLOW | DRIVE = 8;
NET "spi_mosi" LOC = "P24" | IOSTANDARD = LVCMOS25 | SLEW = SLOW | DRIVE = 8;
NET "spi_miso" LOC = "R25" | IOSTANDARD = LVCMOS25;
#
#
#------------------------------------------------------------------------------------------
# End of File
#------------------------------------------------------------------------------------------
#

View File

@ -0,0 +1,623 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2011-2013, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
-- <20> _<> ______ ____<5F> ____<5F> __<5F> __<5F> __<5F><5F>
-- | |/ / ___|<7C> _ \/ ___||<7C> \/<2F> |/ /_<>
-- | ' / |<7C><> | |_) \___ \| |\/| | '_ \
-- | . \ |___|<7C> __/ ___) | |<7C> | | (_) )
-- |_|\_\____|_|<7C><> |____/|_|<7C> |_|\___/
-- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
--
--
-- KCPSM6 reference design on Xilinx KC705 Evaluation Board (www.xilinx.com).
--
-- XC7K325T-1FFG900 Device
--
-- Ken Chapman - Xilinx Ltd.
--
-- 21st September 2012 - Initial version
-- 9th October 2012 - Corrections to comments
-- 18th March 2013 - Alterations to names of modules.
--
--
-- The primary purpose of this reference design is to illustrate how KCPSM6 can implement
-- the signaling and protocol required to communicate and control an SPI Flash memory
-- that was initially connected to the device to facilitate device configuration.
--
-- The design is based on the standard reference designs provided with KCPSM6 (PicoBlaze).
-- These provide a UART-USB connection allowing messages to be displayed on a terminal and
-- for keyboard entries to allow a degree of control and data input. Please refer to the
-- documentation provided with KCPSM6 and the UART macros if you need to know more about
-- PicoBlaze and UART communication. PicoTerm is also supplied with KCPSM6 and ideally
-- suited to this application so please use it.
--
-- In this example the aim is to communicate with the Micron/Numonyx N25Q128 device on the
-- KC705 board. There will be some items specific to this device and board but it is hoped
-- that this design can be a reference starting point for other arrangements. The design
-- implements a classic 4-wire interface and serial communication. Most of the work is
-- perfomed by KCPSM6 which is defined and described in the PSM code provided. However, the
-- starting point is to set up those four connections.
--
-- The SPI Flash memory is initially connected to the device to facilitate configuration so
-- this leads to a very precise set of pins being used. Obviously this design must use those
-- same pins but whilst three of those pins become regular I/O after configuration the CCLK
-- can only be accessed via the STARTUPE2 primitive so that is a critical part of this design
-- to look out for.
--
-- The SPI interface is formed of the signals listed below...
--
-- spi_clk Clock from FPGA to SPI Flash Pin B10 (CCLK) accessed via STARTUPE2
-- spi_cs_b Chip Select from FPGA to SPI Flash Pin U19 (FCS_B)
-- spi_mosi Data from FPGA to SPI Flash Pin P24 (D00)
-- spi_miso Data from SPI Flash to FPGA Pin R25 (D01/DIN)
--
--
-- IMPORTANT: The KC705 board requirs the 'M0' switch on SW13 to be set to '1' so that
-- the 'spi_cs_b' signal is routed through to the SPI Flash rather than the
-- alternative parallel Flash. For Master SPI configuration the required mode
-- switch setting is M[2:0] = "001" so when the SPI Flash is used to
-- configure the device as well the M0 switch will already be High.
--
--
-------------------------------------------------------------------------------------------
--
-- Library declarations
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
--
-------------------------------------------------------------------------------------------
--
--
entity kc705_kcpsm6_spi_flash is
Port ( uart_rx : in std_logic;
uart_tx : out std_logic;
spi_cs_b : out std_logic := '1';
spi_mosi : out std_logic := '0';
spi_miso : in std_logic;
cpu_rst : in std_logic;
clk200_p : in std_logic;
clk200_n : in std_logic);
end kc705_kcpsm6_spi_flash;
--
-------------------------------------------------------------------------------------------
--
-- Start of test architecture
--
architecture Behavioral of kc705_kcpsm6_spi_flash is
--
-------------------------------------------------------------------------------------------
--
-- Components
--
-------------------------------------------------------------------------------------------
--
--
-- declaration of KCPSM6
--
component kcpsm6
generic( hwbuild : std_logic_vector(7 downto 0) := X"00";
interrupt_vector : std_logic_vector(11 downto 0) := X"3FF";
scratch_pad_memory_size : integer := 64);
port ( address : out std_logic_vector(11 downto 0);
instruction : in std_logic_vector(17 downto 0);
bram_enable : out std_logic;
in_port : in std_logic_vector(7 downto 0);
out_port : out std_logic_vector(7 downto 0);
port_id : out std_logic_vector(7 downto 0);
write_strobe : out std_logic;
k_write_strobe : out std_logic;
read_strobe : out std_logic;
interrupt : in std_logic;
interrupt_ack : out std_logic;
sleep : in std_logic;
reset : in std_logic;
clk : in std_logic);
end component;
--
-- Development Program Memory
--
component n25q128_spi_uart_bridge
generic( C_FAMILY : string := "S6";
C_RAM_SIZE_KWORDS : integer := 1;
C_JTAG_LOADER_ENABLE : integer := 0);
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
rdl : out std_logic;
clk : in std_logic);
end component;
--
-- UART Transmitter with integral 16 byte FIFO buffer
--
component uart_tx6
Port ( data_in : in std_logic_vector(7 downto 0);
en_16_x_baud : in std_logic;
serial_out : out std_logic;
buffer_write : in std_logic;
buffer_data_present : out std_logic;
buffer_half_full : out std_logic;
buffer_full : out std_logic;
buffer_reset : in std_logic;
clk : in std_logic);
end component;
--
-- UART Receiver with integral 16 byte FIFO buffer
--
component uart_rx6
Port ( serial_in : in std_logic;
en_16_x_baud : in std_logic;
data_out : out std_logic_vector(7 downto 0);
buffer_read : in std_logic;
buffer_data_present : out std_logic;
buffer_half_full : out std_logic;
buffer_full : out std_logic;
buffer_reset : in std_logic;
clk : in std_logic);
end component;
--
--
-------------------------------------------------------------------------------------------
--
-- Signals
--
-------------------------------------------------------------------------------------------
--
--
--
-- Signals to create and distribute a 100MHz clock from the 200MHz differential input
--
signal clock_divide : std_logic := '0';
signal clk200 : std_logic;
signal clk : std_logic;
--
--
-- Signals used to connect KCPSM6
--
signal address : std_logic_vector(11 downto 0);
signal instruction : std_logic_vector(17 downto 0);
signal bram_enable : std_logic;
signal in_port : std_logic_vector(7 downto 0);
signal out_port : std_logic_vector(7 downto 0);
signal port_id : std_logic_vector(7 downto 0);
signal write_strobe : std_logic;
signal k_write_strobe : std_logic;
signal read_strobe : std_logic;
signal interrupt : std_logic;
signal interrupt_ack : std_logic;
signal kcpsm6_sleep : std_logic;
signal kcpsm6_reset : std_logic;
signal rdl : std_logic;
--
-- Signals used to connect UART_TX6
--
signal uart_tx_data_in : std_logic_vector(7 downto 0);
signal write_to_uart_tx : std_logic;
signal uart_tx_data_present : std_logic;
signal uart_tx_half_full : std_logic;
signal uart_tx_full : std_logic;
signal uart_tx_reset : std_logic;
--
-- Signals used to connect UART_RX6
--
signal uart_rx_data_out : std_logic_vector(7 downto 0);
signal read_from_uart_rx : std_logic;
signal uart_rx_data_present : std_logic;
signal uart_rx_half_full : std_logic;
signal uart_rx_full : std_logic;
signal uart_rx_reset : std_logic;
--
-- Signals used to define baud rate
--
signal baud_count : integer range 0 to 53 := 0;
signal en_16_x_baud : std_logic := '0';
--
--
-- Signals for communication with SPI Flash Memory
--
-- An internal signal is required for 'spi_clk' but 'spi_cs_b', 'spi_mosi' and
-- 'spi_miso' are all direct pin connections
--
signal spi_clk : std_logic := '0';
--
--
-------------------------------------------------------------------------------------------
--
-- Start of circuit description
--
-------------------------------------------------------------------------------------------
--
begin
--
-----------------------------------------------------------------------------------------
-- Create 100MHz clock from 200MHz differential input
-----------------------------------------------------------------------------------------
--
-- A simple toggle flip-flop arrangement is used to divide the clock as no phase
-- relationship with the original 200MHz clock is required in this application.
--
--
-- 200MHz differential input clock
--
clk200_input_buffer: IBUFGDS
port map ( I => clk200_p,
IB => clk200_n,
O => clk200);
clock_generation: process(clk200)
begin
if clk200'event and clk200 = '1' then
clock_divide <= not(clock_divide);
end if;
end process clock_generation;
--
-- BUFG to distribute 100MHz clock
--
clock_100mhz_buffer: BUFG
port map ( I => clock_divide,
O => clk);
--
-----------------------------------------------------------------------------------------
-- Instantiate KCPSM6 and connect to program ROM
-----------------------------------------------------------------------------------------
--
-- The generics can be defined as required. In this case the 'hwbuild' value is used to
-- define a version using the ASCII code for the desired letter and the interrupt vector
-- has been set to 7F0 to provide 16 instructions for an Interrupt Service Routine (ISR)
-- before reaching the end of a 2K memory.
--
--
processor: kcpsm6
generic map ( hwbuild => X"42", -- 42 hex is ASCII character "B"
interrupt_vector => X"7F0",
scratch_pad_memory_size => 256)
port map( address => address,
instruction => instruction,
bram_enable => bram_enable,
port_id => port_id,
write_strobe => write_strobe,
k_write_strobe => k_write_strobe,
out_port => out_port,
read_strobe => read_strobe,
in_port => in_port,
interrupt => interrupt,
interrupt_ack => interrupt_ack,
sleep => kcpsm6_sleep,
reset => kcpsm6_reset,
clk => clk);
--
-- Reset by press button (active Low) or JTAG Loader enabled Program Memory
--
kcpsm6_reset <= rdl or cpu_rst;
--
-- Unused signals tied off until required.
-- Tying to other signals used to minimise warning messages.
--
kcpsm6_sleep <= write_strobe and k_write_strobe; -- Always '0'
interrupt <= interrupt_ack;
--
-- Development Program Memory
-- JTAG Loader enabled for rapid code development.
--
program_rom: n25q128_spi_uart_bridge
generic map( C_FAMILY => "7S",
C_RAM_SIZE_KWORDS => 2,
C_JTAG_LOADER_ENABLE => 1)
port map( address => address,
instruction => instruction,
enable => bram_enable,
rdl => rdl,
clk => clk);
--
-----------------------------------------------------------------------------------------
-- SPI Flash Memory interface
-----------------------------------------------------------------------------------------
--
-- The KC705 board has a 128Mbit SPI Flash connected to the appropriate pins necessary
-- for device configuration. The memory is an Micron/Numonyx N25Q128 device.
--
-- To access this SPI Flash device after configuration three of the configuration pins
-- become regular I/O but the clock must reuse CCLK and that is only accessible via the
-- STARTUPE2 primitive defined here.
--
-- The SPI interface is formed of 4 signals which are 'bit-banged' by KCPSM6 to
-- implement all operations.
-- Pins on XC7K325T-1FFG900
-- spi_clk Clock from FPGA to SPI Flash Pin B10 (CCLK) accessed via STARTUPE2
-- spi_cs_b Chip Select from FPGA to SPI Flash Pin U19 (FCS_B)
-- spi_mosi Data from FPGA to SPI Flash Pin P24 (D00)
-- spi_miso Data from SPI Flash to FPGA Pin R25 (D01/DIN)
--
spi_connect: STARTUPE2
generic map( PROG_USR => "FALSE",
SIM_CCLK_FREQ => 0.0)
port map ( CFGCLK => open,
CFGMCLK => open,
EOS => open,
PREQ => open,
CLK => '0',
GSR => '0',
GTS => '0',
KEYCLEARB => '0',
PACK => '0',
USRCCLKO => spi_clk, -- Provide signal to output on CCLK pin
USRCCLKTS => '0', -- Enable CCLK pin
USRDONEO => '1', -- Drive DONE pin High even though tri-state
USRDONETS => '1' ); -- Maintain tri-state of DONE pin
--
-----------------------------------------------------------------------------------------
-- UART Transmitter with integral 16 byte FIFO buffer
-----------------------------------------------------------------------------------------
--
-- Write to buffer in UART Transmitter at port address 01 hex
--
tx: uart_tx6
port map ( data_in => uart_tx_data_in,
en_16_x_baud => en_16_x_baud,
serial_out => uart_tx,
buffer_write => write_to_uart_tx,
buffer_data_present => uart_tx_data_present,
buffer_half_full => uart_tx_half_full,
buffer_full => uart_tx_full,
buffer_reset => uart_tx_reset,
clk => clk);
--
-----------------------------------------------------------------------------------------
-- UART Receiver with integral 16 byte FIFO buffer
-----------------------------------------------------------------------------------------
--
-- Read from buffer in UART Receiver at port address 01 hex.
--
-- When KCPMS6 reads data from the receiver a pulse must be generated so that the
-- FIFO buffer presents the next character to be read and updates the buffer flags.
--
rx: uart_rx6
port map ( serial_in => uart_rx,
en_16_x_baud => en_16_x_baud,
data_out => uart_rx_data_out,
buffer_read => read_from_uart_rx,
buffer_data_present => uart_rx_data_present,
buffer_half_full => uart_rx_half_full,
buffer_full => uart_rx_full,
buffer_reset => uart_rx_reset,
clk => clk);
--
-----------------------------------------------------------------------------------------
-- RS232 (UART) baud rate
-----------------------------------------------------------------------------------------
--
-- To set serial communication baud rate to 115,200 then en_16_x_baud must pulse
-- High at 1,843,200Hz which is every 54.28 cycles at 100MHz. In this implementation
-- a pulse is generated every 54 cycles resulting is a baud rate of 115,741 baud which
-- is only 0.5% high and well within limits.
--
baud_rate: process(clk)
begin
if clk'event and clk = '1' then
if baud_count = 53 then -- counts 54 states including zero
baud_count <= 0;
en_16_x_baud <= '1'; -- single cycle enable pulse
else
baud_count <= baud_count + 1;
en_16_x_baud <= '0';
end if;
end if;
end process baud_rate;
--
-----------------------------------------------------------------------------------------
-- General Purpose Input Ports.
-----------------------------------------------------------------------------------------
--
-- Two input ports are used with the UART macros. The first is used to monitor the flags
-- on both the UART transmitter and receiver. The second is used to read the data from
-- the UART receiver. Note that the read also requires a 'buffer_read' pulse to be
-- generated.
--
-- This design includes a third input port to read 8 general purpose switches.
--
input_ports: process(clk)
begin
if clk'event and clk = '1' then
case port_id(1 downto 0) is
-- Read UART status at port address 00 hex
when "00" => in_port(0) <= uart_tx_data_present;
in_port(1) <= uart_tx_half_full;
in_port(2) <= uart_tx_full;
in_port(3) <= uart_rx_data_present;
in_port(4) <= uart_rx_half_full;
in_port(5) <= uart_rx_full;
-- Read UART_RX6 data at port address 01 hex
-- (see 'buffer_read' pulse generation below)
when "01" => in_port <= uart_rx_data_out;
-- Unused port address 02 hex
-- when "10" => in_port <= ????;
-- Read SPI serial data MISO at address 03 hex
-- Bit7 used to help with MSB first nature of SPI communication
when "11" => in_port <= spi_miso & "0000000";
-- Don't Care for unsued case(s) ensures minimum logic implementation
when others => in_port <= "XXXXXXXX";
end case;
-- Generate 'buffer_read' pulse following read from port address 01
if (read_strobe = '1') and (port_id(1 downto 0) = "01") then
read_from_uart_rx <= '1';
else
read_from_uart_rx <= '0';
end if;
end if;
end process input_ports;
--
-----------------------------------------------------------------------------------------
-- General Purpose Output Ports
-----------------------------------------------------------------------------------------
--
-- In this design there are two output ports.
-- A simple output port used to output signals to the SPI Flash.
-- A port used to write data directly to the FIFO buffer within 'uart_tx6' macro.
--
output_ports: process(clk)
begin
if clk'event and clk = '1' then
-- 'write_strobe' is used to qualify all writes to general output ports.
if write_strobe = '1' then
-- Signals to SPI Flash Memory at address 04 hex.
-- Bit7 used for MOSI to help with MSB first nature of SPI communication
if port_id(2) = '1' then
spi_clk <= out_port(0);
spi_cs_b <= out_port(1);
spi_mosi <= out_port(7);
end if;
end if;
end if;
end process output_ports;
--
-- Write directly to the FIFO buffer within 'uart_tx6' macro at port address 01 hex.
-- Note the direct connection of 'out_port' to the UART transmitter macro and the
-- way that a single clock cycle write pulse is generated to capture the data.
--
uart_tx_data_in <= out_port;
write_to_uart_tx <= '1' when (write_strobe = '1') and (port_id(0) = '1')
else '0';
--
-----------------------------------------------------------------------------------------
-- Constant-Optimised Output Ports
-----------------------------------------------------------------------------------------
--
-- One constant-optimised output port is used to facilitate resetting of the UART macros.
--
constant_output_ports: process(clk)
begin
if clk'event and clk = '1' then
if k_write_strobe = '1' then
if port_id(0) = '1' then
uart_tx_reset <= out_port(0);
uart_rx_reset <= out_port(1);
end if;
end if;
end if;
end process constant_output_ports;
--
-----------------------------------------------------------------------------------------
--
end Behavioral;
-------------------------------------------------------------------------------------------
--
-- END OF FILE kc705_kcpsm6_spi_flash.vhd
--
-------------------------------------------------------------------------------------------

View File

@ -0,0 +1,840 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2011-2013, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; KCPSM6 reference design: Communication with SPI Flash memory.
;
; Presented on the Xilinx KC705 Evaluation Board (www.xilinx.com) but easily ported to
; other platforms.
;
;
; Ken Chapman - Xilinx Ltd
;
; 25th September 2012 - Initial version
; 18th March 2013 - Constant directives defining ASCII control characters removed
; (pre-defined in KCPSM6 assembler v2.43 or later).
;
;
; INTRODUCTION
;
; The primary purpose of this reference design is to illustrate how KCPSM6 can implement
; the signaling and protocol required to communicate and control an SPI Flash memory
; that was initially connected to the device to facilitate device configuration.
;
; The design is based on the standard reference designs provided with KCPSM6 (PicoBlaze).
; These provide a UART-USB connection allowing messages to be displayed on a terminal and
; for keyboard entries to allow a degree of control and data input. Please refer to the
; documentation provided with KCPSM6 and the UART macros if you need to know more about
; PicoBlaze and UART communication. PicoTerm is also supplied with KCPSM6 and ideally
; suited to this application so please use it.
;
; In this example the aim is to communicate with the Micron/Numonyx N25Q128 device on the
; KC705 board. Please see 'kc705_kcpsm6_uart_spi_flash.vhd' for the hardware arrangement
; and the special requirement for the setting of the 'M0' switch on the KC705 board.
;
; The hardware defines a classic 4-wire SPI interface ready for serial communication...
;
; spi_clk Clock from FPGA (KCPSM6) to SPI Flash
; spi_cs_b Chip Select from FPGA (KCPSM6) to SPI Flash
; spi_mosi Data from FPGA (KCPSM6) to SPI Flash
; spi_miso Data from SPI Flash to FPGA (KCPSM6)
;
; The three output signals are driven directly by a single KCPSM6 output and the input
; signal is read by a single input port. Absolutely everything related to the generation
; of SPI signals and the communication protocol is implemented by KCPSM6 and defined
; within the PSM files provided (detailed descriptions are provided in the PSM code).
;
; This program is only intended to provide a simple example of communication with the
; SPI Flash. The terminal (PicoTerm) provides a convenient way to interact with the
; design and a useful way to develop and verify Flash memory operations. In most real
; application there is no compelling reason to retain the UART sections and certainly the
; SPI code has no dependence on the UART related code.
;
;
;
; NOTE - This PSM file includes further PSM files so these must also be present
; when running the KCPSM6 assembler (v2.00 or later). It is hoped that the
; included files will also be suitable for reuse and inclusion in your own
; programs. For this reason each file contains descriptions of the routines
; that are provided.
;
; PicoTerm_routines.psm - A set of routines to interface with the UART
; macros and use the PicoTerm features.
;
; soft_delays_100mhz.psm - Software delays based on 100MHz clock frequency.
;
;
;------------------------------------------------------------------------------------------
; Port definitions
;------------------------------------------------------------------------------------------
;
;
; SPI Interface to N25Q128 Configuration Flash Memory
; ---------------------------------------------------
;
; See 'N25Q128_SPI_routines.psm' for I/O ports used for SPI communication.
;
;
; UART (for connection with PicoTerm)
; -----------------------------------
;
; See 'PicoTerm_routines.psm' for I/O ports used with UART macros.
;
;
;------------------------------------------------------------------------------------------
; Special Register usage
;------------------------------------------------------------------------------------------
;
; No registers are given special names in this program.
;
;
;------------------------------------------------------------------------------------------
; Scratch Pad Memory Locations (256 Bytes)
;------------------------------------------------------------------------------------------
;
; Scratch pad memory can be reduced to 64 or 128 bytes if desired.
;
;
; PicoTerm features
; -----------------
;
; See 'PicoTerm_routines.psm' for allocation of 18 memory locations.
; These are currently set to memory locations 00 to 12 hex inclusive.
;
;
;------------------------------------------------------------------------------------------
; Useful data constants
;------------------------------------------------------------------------------------------
;
;
;
;------------------------------------------------------------------------------------------
; Initialise the system
;------------------------------------------------------------------------------------------
;
; A delay of 1 second is implemented which is intended to give time for all the hardware
; to settle into a stable condition before starting to doing anything. This can be
; particularly beneficial when dealing with long cables where serial lines can take some
; time to reach the initial idle state following power being applied.
;
cold_start: CALL delay_1s
;
CALL reset_UART_macros ;Reset buffers in UART macros
;
CALL SPI_initialise ;initialise SPI bus
;
; Initialised PicoTerm display and display welcome messages
;
CALL PicoTerm_CLS
CALL welcome_message
;
;
;------------------------------------------------------------------------------------------
; Confirm connection has been made with PicoTerm
;------------------------------------------------------------------------------------------
;
; Before attempting to use any of the special features provided by PicoTerm it is a good
; idea to check that PicoTerm really is connected. This is where the Device Control String
; (DCS) request for a 'Ping' can be used. If a different terminal is being used then the
; plain text messages will be displayed as normal but the 'Ping' request will fail to
; return the response expected. So if this should occur a message will be displayed and
; this program will halt.
;
; Calling the 'PicoTerm_Ping' routine will transmit the Device Control String (DCS)
; to request the 'Ping' from PicoTerm. If PicoTerm is connected then it should respond
; with a DCS containing the (upper case) character 'P'. The response will be intercepted
; by the UART_RX routine and stored in scratch pad memory location 'PicoTerm_Response0'.
; It will take a short while for PicoTerm to respond so the 'Ping' check must wait whilst
; repeatedly calling the UART_RX routine.
;
; The transmission and reception of the 'Ping' DCS sequences (6 characters in total) would
; take ~520us at 115,200 baud rate. Since the program is only going to halt if no response
; occurs it will actually wait much longer. Each call of the UART_RX routine that results
; in its timeout will take ~2,000 clock cycles (~20us at 100MHz) so up to 50,000 (C350 hex)
; calls of UART_RX are made before giving up after approximately one second.
;
LOAD s0, 00 ;clear 'Ping' response location
STORE s0, PicoTerm_Response0
;
CALL PicoTerm_Ping ;request 'Ping' from PicoTerm
;
LOAD sB, C3 ;wait for 50,000 iterations
LOAD sA, 50 ; (~1 second at 100MHz)
;
wait_PT_ping: CALL UART_RX ;discard any characters received
FETCH s0, PicoTerm_Response0
COMPARE s0, "P" ;Test for valid 'Ping' response
JUMP Z, PicoTerm_detected ;continue normally
SUB sA, 01 ;decrement [sB,sA]
SUBCY sB, 00
JUMP NZ, wait_PT_ping
;
; 'Ping' response not received so transmit a text message.
; Note this would still be displayed on other terminals.
;
LOAD sB, no_detect_PT_msg'upper
LOAD sA, no_detect_PT_msg'lower
CALL send_message
PT_halt_here: JUMP PT_halt_here ;Halt program.
;
;
STRING not_PT1$, "ERROR - Unable to detect PicoTerm."
STRING not_PT2$, "Please use PicoTerm v1.30 or later with this design."
;
;
no_detect_PT_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, not_PT1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, not_PT2$
LOAD&RETURN s5, CR
LOAD&RETURN s5, NUL
;
; Once 'Ping' has confirmed that PicoTerm is present, close the 'PicoTerm DCS Transactions'
; window so that only the main window is open.
;
PicoTerm_detected: CALL PicoTerm_hide_DCS
;
;
;------------------------------------------------------------------------------------------
; Confirm SPI communication with Micron/Numonyx N25Q128 device
;------------------------------------------------------------------------------------------
;
; An attempt is made to read the ID of the N25Q128 device. The first 3 bytes of the
; response to an RDID instruction should be 20, BA, 18 hex for this device so these values
; will be displayed and tested.
;
; Note that on the KC705 board the 'M0' switch of SW13 must be set to '1' otherwise the
; 'spi_cs_b' signal will be routed to the parallel Flash memory on the board rather than
; N25Q128 SPI device. Hence the most likely reason for this test failing is due to the
; setting of the 'M0' switch and therefore the error message provides suitable advice.
; Of course the 'M0' switch also provides a good way to test this PSM code.
;
LOAD sB, SPI_check1_msg'upper
LOAD sA, SPI_check1_msg'lower
CALL send_message
;
; N25Q128 'RDID' Instruction
;
; The response can be up to 20-bytes long but only the first 3-bytes are used in
; this design as they are the same for all N25Q128 devices. The remaining bytes
; can be factory programmed to customer requirements.
;
CALL read_spi_flash_ID ;Read Flash ID into ; [s9,s8,s7]
LOAD s4, s9 ; display response
CALL send_hex_byte
CALL send_space
LOAD s4, s8
CALL send_hex_byte
CALL send_space
LOAD s4, s7
CALL send_hex_byte
;
COMPARE s9, 20 ;test for expected response
COMPARECY s8, BA
COMPARECY s7, 18
JUMP Z, N25Q128_detected
;
; Unexpected response from RDID attempt
;
CALL PicoTerm_text_Red
LOAD sB, SPI_fail_msg'upper
LOAD sA, SPI_fail_msg'lower
CALL send_message
SPI_halt_here: JUMP SPI_halt_here ;Halt program.
;
;
; Text messages for this section
;
STRING SPI_check1$, "Reading N25Q128 device ID... "
STRING SPI_fail1$, "ERROR - Unable to detect N25Q128 device."
STRING SPI_fail2$, "Please check that 'M0' switch on KC705 board is set to '1'."
;
SPI_check1_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, SPI_check1$
LOAD&RETURN s5, NUL
;
SPI_fail_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, SPI_fail1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, SPI_fail2$
LOAD&RETURN s5, CR
LOAD&RETURN s5, NUL
;
N25Q128_detected:
;
;
;------------------------------------------------------------------------------------------
; Main Program
;------------------------------------------------------------------------------------------
;
; The 'main' program allows the user to read, write and erase the N25Q128 device.
;
; WARNING - You are responsible for your own actions!
;
;
main_with_menu: CALL PicoTerm_text_Blue
CALL display_menu
;
; Display prompt and wait for user input.
; Then test input for valid section and either invoke operation or display message.
;
main_prompt: CALL PicoTerm_text_Blue
CALL send_CR ;prompt user to enter a command
CALL send_CR
LOAD s5, ">"
CALL UART_TX
CALL send_space
;
wait_main: CALL UART_RX ;wait for user input
JUMP Z, wait_main
CALL upper_case ;accept upper or lower case inputs
CALL UART_TX ;echo user input
;
COMPARE s5, "H" ;Help
JUMP Z, main_with_menu
;
COMPARE s5, "R" ;Read Page
JUMP Z, read_page_command
;
COMPARE s5, "W" ;Write Byte
JUMP Z, write_byte_command
;
COMPARE s5, "E" ;Erase Sector
JUMP Z, erase_sector_command
;
LOAD s5, "?" ;For all other inputs display ??
CALL UART_TX
CALL UART_TX
JUMP main_prompt
;
;
;------------------------------------------------------------------------------------------
; 'R' Read Page Command
;------------------------------------------------------------------------------------------
;
; Obtain a 24-bit address from the user and then read and display the 256 bytes of Flash
; memory in which that address is present.
;
; There are 256 Sectors formed of 256 pages. So in practical terms...
; address[23:16] = Sector (Register 's9')
; address[15:9] = Page (Register 's8')
; address[7:0] = Byte (Register 's7')
;
read_page_command: CALL obtain_address ;24-bit address in [s9,s8,s7]
LOAD s7, 00 ;clear byte address for start of page
;
CALL PicoTerm_text_Magenta
CALL send_CR
read_line_loop: LOAD s6, 16'd ;16 bytes per line
CALL send_CR
LOAD s4, s9 ;display 24-bit address
CALL send_hex_byte
LOAD s4, s8
CALL send_hex_byte
LOAD s4, s7
CALL send_hex_byte
CALL send_space
CALL send_space
CALL send_space
read_byte_loop: CALL read_spi_byte ;read byte into 's2'
LOAD s4, s2 ;display byte
CALL send_hex_byte
CALL send_space
ADD s7, 01 ;count bytes
JUMP C, end_read_SPI_page
SUB s6, 1'd
JUMP NZ, read_byte_loop
JUMP read_line_loop
;
end_read_SPI_page: CALL send_CR
JUMP main_prompt
;
;
;------------------------------------------------------------------------------------------
; 'W' Write Byte Command
;------------------------------------------------------------------------------------------
;
; Obtain a 24-bit address and 8-bit data value from the user and then write to Flash
; memory. Remember that bits can only be changed from '1' to '0' when writing.
;
write_byte_command: CALL obtain_address ;24-bit address in [s9,s8,s7]
CALL obtain_data ;8-bit data in s2
;
CALL write_spi_byte ;write 's2' into [s9,s8,s7]
;
CALL PicoTerm_text_Green
CALL send_Ok
JUMP main_prompt
;
;
;------------------------------------------------------------------------------------------
; 'E' Erase Sector Command
;------------------------------------------------------------------------------------------
;
; Obtain a 24-bit address from the user and then erase the sector in which that address
; falls. The N25Q128 memory is 16M-bytes and organised into 256 Sectors. Each Sector
; contains 256 Pages which in turn contain 256 Bytes. So in terms of the 24-bit address...
;
; address[23:16] = Sector (Register 's9')
; address[15:9] = Page (Register 's8')
; address[7:0] = Byte (Register 's7')
;
; Hence it is address[23:16] that defines the Sector that will be erased and will result
; in 65,536 bytes (64KB) being cleared to FF hex.
;
erase_sector_command: CALL PicoTerm_text_Black
LOAD sB, erase_msg'upper ;prompt for address
LOAD sA, erase_msg'lower
CALL send_message
;
CALL obtain_address ;24-bit address in [s9,s8,s7]
;
CALL erase_spi_sector ;erase sector with address [s9,s8,s7]
;
CALL PicoTerm_text_Green
CALL send_Ok
JUMP main_prompt
;
;
;
; Text message used in this section
;
STRING erase1$, "WARNING - This command will erase 64KB (65,536 Bytes) of memory!"
STRING erase2$, " The whole of the sector in which the address falls will be erased."
STRING erase3$, " Press 'CPU RST' button if you want to stop now!"
;
erase_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, erase1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, erase2$
LOAD&RETURN s5, CR
LOAD&RETURN s5, erase3$
LOAD&RETURN s5, NUL
;
;
;------------------------------------------------------------------------------------------
; Obtain 24-bit address from user
;------------------------------------------------------------------------------------------
;
; Prompt user to enter a 24-bit address and return it in [s9,s8,s7].
; If user makes a mistake then keep prompting until they get it right!
;
obtain_address: CALL PicoTerm_text_Black
LOAD sB, prompt_address_msg'upper ;prompt for address
LOAD sA, prompt_address_msg'lower
CALL send_message
;
LOAD sE, 6'd ;obtain 6-digit value
CALL obtain_value ;24-bit value returned in [sC,sB,sA]
JUMP C, bad_address_input ;Carry set for a bad hex value
LOAD s9, sC ;return address in [s9,s8,s7]
LOAD s8, sB
LOAD s7, sA
RETURN
;
bad_address_input: CALL PicoTerm_text_Red
LOAD sB, bad_address_msg'upper
LOAD sA, bad_address_msg'lower
CALL send_message
JUMP obtain_address
;
;
; Text messages used in this section
;
STRING prompt_address$, "Please enter a 24-bit (6-digit hexadecimal) address > "
STRING bad_address$, "Sorry, that was not a valid 6-digit hexadecimal address!"
;
prompt_address_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, prompt_address$
LOAD&RETURN s5, NUL
;
bad_address_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, bad_address$
LOAD&RETURN s5, NUL
;
;
;------------------------------------------------------------------------------------------
; Obtain 8-bit data from user
;------------------------------------------------------------------------------------------
;
; Prompt user to enter an 8-bit data byte and return it in 's2'.
; If user makes a mistake then keep prompting until they get it right!
;
obtain_data: CALL PicoTerm_text_Black
LOAD sB, prompt_data_msg'upper ;prompt for address
LOAD sA, prompt_data_msg'lower
CALL send_message
;
LOAD sE, 2'd ;obtain 2-digit value
CALL obtain_value ;8-bit value returned in sA
JUMP C, bad_data_input ;Carry set for a bad hex value
LOAD s2, sA ;return data in s2
RETURN
;
bad_data_input: CALL PicoTerm_text_Red
LOAD sB, bad_data_msg'upper
LOAD sA, bad_data_msg'lower
CALL send_message
JUMP obtain_data
;
;
; Text messages used in this section
;
STRING prompt_data$, "Please enter an 8-bit data (2-digit hexadecimal) value > "
STRING bad_data$, "Sorry, that was not a valid 2-digit hexadecimal value!"
;
prompt_data_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, prompt_data$
LOAD&RETURN s5, NUL
;
bad_data_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, bad_data$
LOAD&RETURN s5, NUL
;
;
;------------------------------------------------------------------------------------------
; Welcome Message.
;------------------------------------------------------------------------------------------
;
; The welcome message includes a display of the version information available from the
; assembler and the 'hwbuild' from the instantiation of KCPSM6 in the hardware design.
;
welcome_message: LOAD sB, welcome_msg'upper
LOAD sA, welcome_msg'lower
CALL send_message
HWBUILD s5 ;hardware version defines ASCII letter
CALL UART_TX
CALL send_CR
RETURN
;
; Welcome message
;
STRING banner1$, " _ ______ ____ ____ __ __ __"
STRING banner2$, " | |/ / ___| _ \/ ___|| \/ |/ /_"
STRING banner3$, " | ' / | | |_) \___ \| |\/| | '_ \"
STRING banner4$, " | . \ |___| __/ ___) | | | | (_) )"
STRING banner5$, " |_|\_\____|_| |____/|_| |_|\___/"
;
; Welcome message
;
STRING welcome1$, "Reference Design: SPI Flash Memory Controller on KC705 Board"
STRING welcome2$, " Memory initially used for device configuration"
STRING welcome3$, "Assembly Date: "
STRING welcome4$, " Time: "
STRING welcome5$, "Assembler Version: "
STRING welcome6$, "Hardware Design: "
;
;
welcome_msg: LOAD&RETURN s5, banner1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner2$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner3$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner4$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner5$
LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome2$
LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome3$
LOAD&RETURN s5, datestamp$
LOAD&RETURN s5, welcome4$
LOAD&RETURN s5, timestamp$
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome5$
LOAD&RETURN s5, KCPSM6_version$
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome6$
LOAD&RETURN s5, NUL
;
;
;------------------------------------------------------------------------------------------
; Routine to transmit a simple 'Menu'.
;------------------------------------------------------------------------------------------
;
display_menu: LOAD sB, menu_msg'upper
LOAD sA, menu_msg'lower
CALL send_message
RETURN
;
; Menu message
;
STRING menu1$, "Menu"
STRING menu2$, " H - Display this menu"
STRING menu3$, " R - Read (Page)"
STRING menu4$, " W - Write (Byte)"
STRING menu5$, " E - Erase (Sector)"
;
menu_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, menu1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, menu2$
LOAD&RETURN s5, CR
LOAD&RETURN s5, menu3$
LOAD&RETURN s5, CR
LOAD&RETURN s5, menu4$
LOAD&RETURN s5, CR
LOAD&RETURN s5, menu5$
LOAD&RETURN s5, CR
LOAD&RETURN s5, NUL
;
;
;------------------------------------------------------------------------------------------
; Send a message to the UART
;------------------------------------------------------------------------------------------
;
; A message is transmitted to the USB-UART.
; The start address of the message must be provided in [sB,sA].
; Terminate the transmission with a NULL character (00 hex).
;
send_message: CALL@ (sB, sA)
COMPARE s5, 00 ;terminate on NUL character
RETURN Z
CALL UART_TX
ADD sA, 1'd
ADDCY sB, 0'd
JUMP send_message
;
;
;------------------------------------------------------------------------------------------
; Send Carriage Return to UART
;------------------------------------------------------------------------------------------
;
; Registers used s0, s1, s2, and s5.
;
send_CR: LOAD s5, CR
JUMP UART_TX ;includes RETURN
;
;
;------------------------------------------------------------------------------------------
; Send Carriage Return, 'Ok' and Carriage Return to UART
;------------------------------------------------------------------------------------------
;
; Registers used s0, s1, s2, and s5.
;
send_Ok: CALL send_CR
LOAD s5, "O"
CALL UART_TX
LOAD s5, "k"
CALL UART_TX
JUMP send_CR ;includes RETURN
;
;
;------------------------------------------------------------------------------------------
; Send a Space to UART
;------------------------------------------------------------------------------------------
;
; Registers used s0, s1, s2, and s5.
;
send_space: LOAD s5, " "
JUMP UART_TX ;includes RETURN
;
;
;------------------------------------------------------------------------------------------
; Send Hex Value of Byte to UART
;------------------------------------------------------------------------------------------
;
; Value provided in register 's4' is sent as ASCII HEX to the UART transmitter.
;
; Registers used s0, s4 (preserved) and s5.
;
send_hex_byte: LOAD s5, s4 ;isolate upper nibble
SR0 s5
SR0 s5
SR0 s5
SR0 s5
CALL hex_to_ASCII ; convert to ASCII
CALL UART_TX ;send upper digit to UART
LOAD s5, s4 ;isolate lower nibble
AND s5, 0F
CALL hex_to_ASCII ; convert to ASCII
CALL UART_TX ;send lower digit to UART
RETURN
;
; Convert value 00 to 0F provided in 's5' into ASCII character in 's5'
;
; Register used s5
;
hex_to_ASCII: SUB s5, 0A ;test if value is in range 0 to 9
JUMP C, number_char
ADD s5, 07 ;ASCII char A to F in range 41 to 46
number_char: ADD s5, 3A ;ASCII char 0 to 9 in range 30 to 40
RETURN
;
;
;------------------------------------------------------------------------------------------
; Converts character to upper case
;------------------------------------------------------------------------------------------
;
; Tests and converts character in 's5' (if necessary).
;
; To convert character to upper case
;
; If the character is in the range 'a' to 'z', it is converted
; to the equivalent upper case character in the range 'A' to 'Z'.
; All other characters remain unchanged.
;
upper_case: COMPARE s5, "a" ;eliminate character codes below 'a' (61 hex)
RETURN C
COMPARE s5, 7B ;eliminate character codes above 'z' (7A hex)
RETURN NC
AND s5, 11011111'b ;force bit5 Low to convert to upper case
RETURN
;
;
;------------------------------------------------------------------------------------------
; Convert ASCII character to an equivalent HEX value.
;------------------------------------------------------------------------------------------
;
; Converts the ASCII character presented in 's5' to an equivalent HEX value.
; If character is not valid for hex, then CARRY is set on return.
;
; Register used s5
;
ASCII_to_hex: ADD s5, B9 ;test for above ASCII code 46 ('F')
RETURN C
SUB s5, E9 ;normalise 0 to 9 with A-F in 11 to 16 hex
RETURN C ;reject below ASCII code 30 ('0')
SUB s5, 11 ;isolate A-F down to 00 to 05 hex
JUMP NC, ASCII_letter
ADD s5, 07 ;test for above ASCII code 46 ('F')
RETURN C
SUB s5, F6 ;convert to range 00 to 09
RETURN
ASCII_letter: ADD s5, 0A ;convert to range 0A to 0F
RETURN
;
;
;------------------------------------------------------------------------------------------
; Read ASCII-HEX value up to 8-digits (for 32-bit value) from UART
;------------------------------------------------------------------------------------------
;
; Read up to 8 hex characters from UART and convert to a binary value in the [sD,sC,sB,sA]
; register set. The number of characters to be read must be defined in sE. When less than
; 8 characters are read the value is returned in the least significant bits of the register
; set with the 8-bits above the defined value being zero to ensure ensuring that the upper
; nibble will be zero if an odd number of digits are read.
;
; If any character received from the UART is not in the range 0 to F then the routine will
; end immediately with the CARRY flag set and this should be checked my the calling process
; upon return.
;
obtain_value: LOAD sA, 00 ;initialise potentially unused bits to zero
obtain_digit: CALL UART_RX ;wait for a character and return in s5
JUMP Z, obtain_digit ;continue to wait if timeout occurs
CALL UART_TX ;echo character as entered
CALL upper_case ;convert to upper case if necessary
CALL ASCII_to_hex ;convert value in s5 to hex nibble
RETURN C ;If invalid hex digit then return immediately
LOAD s0, 4'd ;shift [sD,sC,sB,sA] left by 4 bits
build_value: SL0 sA ; to make space for new digit value
SLA sB
SLA sC
SLA sD
SUB s0, 1'd
JUMP NZ, build_value
OR sA, s5 ;merge value of new digit into existing value
SUB sE, 01 ;count number of digits obtained
JUMP NZ, obtain_digit
RETURN
;
;
;------------------------------------------------------------------------------------------
; Include PSM files
;------------------------------------------------------------------------------------------
;
; The INCLUDE directive enables commonly routines to be kept in their own PSM files and
; easily reused in different programs (i.e. avoiding 'cut and paste'). It also allows
; each PSM to remain a more manageable size.
;
;
; Routines that implement interface with UART macros and control PicoTerm.
; ------------------------------------------------------------------------
;
INCLUDE "PicoTerm_routines.psm"
;
;
; Software Delays
; ---------------
;
INCLUDE "soft_delays_100mhz.psm"
;
;
; SPI communication with Micron/Numonyx N25Q128 device
; ----------------------------------------------------
;
INCLUDE "N25Q128_SPI_routines.psm"
;
;
;------------------------------------------------------------------------------------------
; Interrupt Service Routine (ISR)
;------------------------------------------------------------------------------------------
;
; Interrupts are not currently used in this program but in preparation the location of
; the ISR has been defined to corresponding with the 'interrupt_vector' address defined
; in the instantiation of KCPSM6. In this instance the vector is 7F0 hex which means there
; are 16 instructions available before reaching the end of a 2K program memory. Of course
; this can all be modified.
;
ADDRESS 7F0
;
;
ISR: RETURNI DISABLE
;
;
;------------------------------------------------------------------------------------------
; End of Program
;------------------------------------------------------------------------------------------
;

View File

@ -0,0 +1,109 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2012-2013, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; PicoBlaze Reference Design.
;
;
; Ken Chapman - Xilinx Ltd
;
; 6th September 2012 - Initial version
; 18th March 2013 - Addition of 20ms delay
;
; This file contains routines that implement delays in software. It should be recognised
; that the delay periods are the result of executing instructions, and because every
; instruction takes 2 clock cycles to execute, it is possible to determine the exact
; delay period. However, besides the obvious dependency on the clock frequency, it
; should also be recognised that any interrupts to KCPSM6 (or use of sleep mode) will
; impact the timing. In general, it is better only to use soft delay routines in
; situations where approximate timing is adequate; in those situations KCPSM6 will often
; exceed your requirements.
;
;
;------------------------------------------------------------------------------------------
; Software Delays based on 100MHz clock
;------------------------------------------------------------------------------------------
;
; The number of iterations of a delay loop required to form each delay required are
; loaded into the register set [s2,s1,s0] and then the delay loop is started.
;
; Registers used s0, s1, s2
;
; 1ms is 10,000 x 100ns (10,000 = 002710 hex)
;
delay_1ms: LOAD s2, 00
LOAD s1, 27
LOAD s0, 10
JUMP software_delay
;
; 20ms is 200,000 x 100ns (200,000 = 030D40 hex)
;
delay_20ms: LOAD s2, 03
LOAD s1, 0D
LOAD s0, 40
JUMP software_delay
;
;
; 1s is 10,000,000 x 100ns (10,000,000 = 989680 hex)
;
delay_1s: LOAD s2, 98
LOAD s1, 96
LOAD s0, 80
JUMP software_delay
;
; The delay loop decrements [s2,s1,s0] until it reaches zero
; Each decrement cycle is 5 instructions which is 10 clock cycles (100ns at 100MHz)
;
software_delay: LOAD s0, s0 ;pad loop to make it 10 clock cycles (5 instructions)
SUB s0, 1'd
SUBCY s1, 0'd
SUBCY s2, 0'd
JUMP NZ, software_delay
RETURN
;
;
;------------------------------------------------------------------------------------------
; End of 'soft_delays_100mhz.psm'
;------------------------------------------------------------------------------------------
;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,111 @@
#
#------------------------------------------------------------------------------------------
# Copyright <20> 2011-2012, Xilinx, Inc.
# This file contains confidential and proprietary information of Xilinx, Inc. and is
# protected under U.S. and international copyright and other intellectual property laws.
#------------------------------------------------------------------------------------------
#
# Disclaimer:
# This disclaimer is not a license and does not grant any rights to the materials
# distributed herewith. Except as otherwise provided in a valid license issued to
# you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
# MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
# DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
# INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
# OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
# (whether in contract or tort, including negligence, or under any other theory
# of liability) for any loss or damage of any kind or nature related to, arising
# under or in connection with these materials, including for any direct, or any
# indirect, special, incidental, or consequential loss or damage (including loss
# of data, profits, goodwill, or any type of loss or damage suffered as a result
# of any action brought by a third party) even if such damage or loss was
# reasonably foreseeable or Xilinx had been advised of the possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-safe, or for use in any
# application requiring fail-safe performance, such as life-support or safety
# devices or systems, Class III medical devices, nuclear facilities, applications
# related to the deployment of airbags, or any other applications that could lead
# to death, personal injury, or severe property or environmental damage
# (individually and collectively, "Critical Applications"). Customer assumes the
# sole risk and liability of any use of Xilinx products in Critical Applications,
# subject only to applicable laws and regulations governing limitations on product
# liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
#
#------------------------------------------------------------------------------------------
#
# Constraints for 'kc705_kcpsm6_xadc.vhd'.
#
# KC705 Board Rev.D (www.xilinx.com)
#
# XC7K325T-1FFG900 Device
#
# Ken Chapman - Xilinx Ltd
#
# 18th December 2012 - Initial Release.
#
#
#
#------------------------------------------------------------------------------------------
# Timing Constraints
#------------------------------------------------------------------------------------------
#
#
# Period constraint for 200MHz operation
#
NET "clk" TNM_NET = "clk";
TIMESPEC TS_100MHZ_clk = PERIOD "clk" 5.0ns HIGH 50%;
#
#
#------------------------------------------------------------------------------------------
# Pin Constraints
#------------------------------------------------------------------------------------------
#
#
# Analog Inputs
# -------------
#
# The dedicated analog input pair VP and VN are used but being dedicated do not need to
# be constrained. Likewise two auxiliary analog input pairs are used but these too are
# automatically constrained by the connections to the XADC primitive. Note that when any
# auxiliary analog pair are used these pins are no longer available for digital I/O.
#
# Analog Device XADC Header on KC705 Board
# Input Pin (J46) Pin
#
# VP R15 2
# VN T14 1
# VAUXP[0] J23 3
# VAUXN[0] J24 6
# VAUXP[8] L22 8
# VAUXN[8] L23 7
#
#
# 200MHz Differential Clock (SYSCLK).
# -----------------------------------
#
NET "clk200_p" LOC = "AD12" | IOSTANDARD = DIFF_SSTL15;
NET "clk200_n" LOC = "AD11" | IOSTANDARD = DIFF_SSTL15;
#
#
# USB-UART
# --------
#
NET "uart_rx" LOC = "M19" | IOSTANDARD = LVCMOS25;
NET "uart_tx" LOC = "K24" | IOSTANDARD = LVCMOS25 | SLEW = SLOW | DRIVE = 4;
#
#
# CPU_RST (SW7)
# -------------
#
# Press switch is active High
#
NET "cpu_rst" LOC = "AB7" | IOSTANDARD = LVCMOS15;
#
#
#------------------------------------------------------------------------------------------
# End of File
#------------------------------------------------------------------------------------------
#

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,116 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2012-2013, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; PicoBlaze Reference Design.
;
;
; Ken Chapman - Xilinx Ltd
;
; 24th December 2012 - Initial version
; 2nd August 2013 - 100ms delay and correction to comment
;
; This file contains routines that implement delays in software. It should be recognised
; that the delay periods are the result of executing instructions, and because every
; instruction takes 2 clock cycles to execute, it is possible to determine the exact
; delay period. However, besides the obvious dependency on the clock frequency, it
; should also be recognised that any interrupts to KCPSM6 (or use of sleep mode) will
; impact the timing. In general, it is better only to use soft delay routines in
; situations where approximate timing is adequate; in those situations KCPSM6 will often
; exceed your requirements.
;
;
;------------------------------------------------------------------------------------------
; Software Delays based on 200MHz clock
;------------------------------------------------------------------------------------------
;
; The number of iterations of a delay loop required to form each delay required are
; loaded into the register set [s2,s1,s0] and then the delay loop is started.
;
; Registers used s0, s1, s2
;
; 1ms is 20,000 x 50ns (20,000 = 004E200 hex)
;
delay_1ms: LOAD s2, 00
LOAD s1, 4E
LOAD s0, 20
JUMP software_delay
;
;
; 100ms is 2,000,000 x 50ns (2,000,000 = 1E8480 hex)
;
delay_100ms: LOAD s2, 1E
LOAD s1, 84
LOAD s0, 80
JUMP software_delay
;
;
; 500ms is 10,000,000 x 50ns (10,000,000 = 989680 hex)
;
delay_500ms: LOAD s2, 98
LOAD s1, 96
LOAD s0, 80
JUMP software_delay
;
;
; 1s is 2 x 500ms (largest delay with 24-bit value is 17,777,215 x 50ns = 838.86ms)
;
delay_1s: CALL delay_500ms
JUMP delay_500ms
;
; The delay loop decrements [s2,s1,s0] until it reaches zero
; Each decrement cycle is 5 instructions which is 10 clock cycles (50ns at 100MHz)
;
software_delay: LOAD s0, s0 ;pad loop to make it 10 clock cycles (5 instructions)
SUB s0, 1'd
SUBCY s1, 0'd
SUBCY s2, 0'd
JUMP NZ, software_delay
RETURN
;
;
;------------------------------------------------------------------------------------------
; End of 'soft_delays_200mhz.psm'
;------------------------------------------------------------------------------------------
;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,625 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2012-2013, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; PicoBlaze Reference Design.
;
;
; Routines for XADC Communication, Control and Monitoring
;
; Ken Chapman - Xilinx Ltd
;
; 9th January 2013 - Initial Version
;
;
; NOTE - This is not a standalone PSM file. Include this file in a program that
; then calls these routines and works with the values in scratch pad memory.
;
; INCLUDE "xadc_routines.psm"
;
;
; IMPORTANT - These routines interact with input and output ports which must
; be appropriately defined to interface with XADC. The CONSTANT
; directives defined below must correspond with the port assignments.
;
;
; INTRODUCTION
; ------------
;
; This file implements two routines that allow the XADC registers to be read or written
; using the DRP and KCPSM6 interface circuit defined in the hardware. Please see the
; 'kc705_kcpsm6_xadc.vhd' reference design which contains full descriptions of the
; interface and various KCPSM6 input and output ports allocated to it.
;
; This file also includes routines which help to interpret and convert register values
; into their corresponding voltage and temperature values.
;
;------------------------------------------------------------------------------------------
; Hardware Constants
;------------------------------------------------------------------------------------------
;
; The following constants define the input and output ports allocated to the XADC DRP
; interface. These constants reflect the ports used in the 'kc705_kcpsm6_xadc.vhd'
; reference design file and should be modified if different ports are allocated in your
; own designs.
;
; Prior to initiating a read or write transaction, KCPSM6 must present the 7-bit address of
; the target XADC register to the DRP interface using the following output port.
;
CONSTANT XADC_register_address, 80 ; register address[6:0]
;
; If a new value is to be written to an XADC configuration register then the 16-bit value
; must also be presented to the DRP interface using the following pair of output ports.
;
CONSTANT XADC_write_data0, 82 ; new register value[7:0]
CONSTANT XADC_write_data1, 83 ; new register value[15:8]
;
; To initiate a transaction with XADC a value is output to a Constant Optimised Output
; Port. The value of bit0 defines the state of DWE for read (0) or write (1).
;
CONSTANT XADC_start_port, 02 ; 'k_write_strobe' starts transaction
CONSTANT XADC_read_mode, 00000000'b ; DWE = 0 read - bit0
CONSTANT XADC_write_mode, 00000001'b ; DWE = 1 write - bit0
;
; Once a transaction has been started, the hardware will present a 'transaction in progress'
; flag 'tip' to KCPSM6 via the 'XADC_status_port' defined below. KCPSM6 must wait for 'tip'
; to be Low (0) before proceeding to read the register value requested or starting another
; transaction. The status port also provides KCPSM6 with the ability to check if XADC is
; being used, or has been modified, by the JTAG interface. Finally, this port is also used
; to observe the over temperature alarm signal (OT).
;
CONSTANT XADC_status_port, 04
CONSTANT XADC_tip, 00000001'b ; 'transaction in progress' - bit0
CONSTANT XADC_JTAG_busy, 00000010'b ; JTAG busy - bit1
CONSTANT XADC_JTAG_locked, 00000100'b ; JTAG locked - bit2
CONSTANT XADC_JTAG_modified, 00001000'b ; JTAG modified - bit3
CONSTANT XADC_OT_alarm, 00010000'b ; OT over temperature alarm - bit4
;
; Following completion of a read transaction the 16-bit contents of the XADC register can
; be read from the following pair of input ports.
;
CONSTANT XADC_read_data0, 02 ; register value[7:0]
CONSTANT XADC_read_data1, 03 ; register value[15:8]
;
; As well as the 'OT' alarm observed via the 'XADC_status_port', XADC generates up to
; 7 more alarm signals (plus an 8th alarm which is the logical-OR of the 7 alarms). The
; following constant define the input port used by KCPSM6 to observe these alarms and the
; bits to which they have been allocated.
;
CONSTANT XADC_alarm_port, 05
CONSTANT XADC_ALM0_Temperature, 00000001'b ; ALM(0) Temperature - bit0
CONSTANT XADC_ALM1_VCCINT, 00000010'b ; ALM(1) VCCINT - bit1
CONSTANT XADC_ALM2_VCCAUX, 00000100'b ; ALM(2) VCCAUX - bit2
CONSTANT XADC_ALM3_VCCBRAM, 00001000'b ; ALM(3) VCCBRAM - bit3
CONSTANT XADC_ALM4_VCCPINT, 00010000'b ; ALM(4) VCCPINT (Zynq only) - bit4
CONSTANT XADC_ALM5_VCCPAUX, 00100000'b ; ALM(5) VCCPAUX (Zynq only) - bit5
CONSTANT XADC_ALM6_VCCO_DDR, 01000000'b ; ALM(6) VCCO_DDR (Zynq only) - bit6
CONSTANT XADC_ALM7, 10000000'b ; ALM(7) Any alarm - bit7
;
;
;------------------------------------------------------------------------------------------
; Routine to read and return the contents of an XADC register.
;------------------------------------------------------------------------------------------
;
; Reads XADC register via DRP.
; The 7-bit address of the register to be read must be provided in sA.
; The 16-bit register value will be returned in register pair [s9,s8].
;
; Registers used s0, s8, s9 (preserved) and sA.
;
;
read_XADC: OUTPUT sA, XADC_register_address ;set address (DADDR)
OUTPUTK XADC_read_mode, XADC_start_port ;Start read transaction (DWE = 0)
CALL wait_for_XADC_DRP ;wait for DRP to complete
INPUT s8, XADC_read_data0 ;read register value into [s9,s8]
INPUT s9, XADC_read_data1
RETURN
;
;
;------------------------------------------------------------------------------------------
; Routine to write new value to an XADC configuration register.
;------------------------------------------------------------------------------------------
;
; Write XADC register via DRP.
; The address of the register to be written must be provided in sA.
;
; NOTE - There are only 32 writable configuration registers so the
; register address should be in the range 40 to 5F hex.
;
; The 16-bit value to be stored in the configuration register must be provided in
; register pair [s9,s8].
;
; Registers used s0, s8 (preserved), s9 (preserved) and sA (preserved).
;
write_XADC: OUTPUT sA, XADC_register_address ;set address (DADDR)
OUTPUT s8, XADC_write_data0 ;set data (DI[7:0])
OUTPUT s9, XADC_write_data1 ;set data (DI[15:8])
OUTPUTK XADC_write_mode, XADC_start_port ;Start write transaction (DWE = 1)
;
; Test the 'transaction in progress' until it is observed to be Low.
; This will complete a write transaction or indicates when a register value
; is available to be read following a read transaction.
;
wait_for_XADC_DRP: INPUT s0, XADC_status_port
TEST s0, XADC_tip
JUMP NZ, wait_for_XADC_DRP
RETURN
;
;
;------------------------------------------------------------------------------------------
; Routine to read the XADC status and alarm signals.
;------------------------------------------------------------------------------------------
;
; This routine is a simple read of the input ports associated with the XADC status and
; alarm signals with the bits returned in registers 's8' and 's9'.
;
; Hint - Constants have been defined to identify the bit allocations.
; e.g. TEST s8, XADC_ALM1_VCCINT will test the VCCINT alarm bit.
;
;
; Register Bit XADC Signal CONSTANT defined to isolate bit
;
; s8 0 ALM(0) Temperature XADC_ALM0_Temperature
; s8 1 ALM(1) VCCINT XADC_ALM1_VCCINT
; s8 2 ALM(2) VCCAUX XADC_ALM2_VCCAUX
; s8 3 ALM(3) VCCBRAM XADC_ALM3_VCCBRAM
; s8 4 ALM(4) VCCPINT (Zynq only) XADC_ALM4_VCCPINT
; s8 5 ALM(5) VCCPAUX (Zynq only) XADC_ALM5_VCCPAUX
; s8 6 ALM(6) VCCO_DDR (Zynq only) XADC_ALM6_VCCO_DDR
; s8 7 ALM(7) Any alarm XADC_ALM7
;
; s9 1 JTAG busy XADC_JTAG_busy
; s9 2 JTAG locked XADC_JTAG_locked
; s9 3 JTAG modified XADC_JTAG_modified
; s9 4 OT over temperature alarm XADC_OT_alarm
;
; Registers s8 and s9.
;
read_XADC_status: INPUT s8, XADC_alarm_port
INPUT s9, XADC_status_port
AND s9, 00011110'b ;mask unused bits
RETURN
;
;
;------------------------------------------------------------------------------------------
; Routine to convert XADC Temperature sample to degrees centigrade
;------------------------------------------------------------------------------------------
;
; Die temperature is obtained by reading the temperature status register (00 hex) from
; XADC (obviously the die temperature channel must have been sampled for the value to be
; valid and reasonably current).
;
; The temperature sample obtained when reading the status register is 16-bits. Of these,
; it is the 12 most significant bits which are immediately trustworthy and represent a die
; temperature with a theoretical range from -273degC to +230.7degC. The transfer function
; for the 12-bit sample is...
;
; Temperature in degC = ((12-bit_ADC_code x 503.975) / 4096) - 273.15
;
; However, the use of sample averaging (built-in to XADC when enabled, in the application
; or a combination of both) can exploit the 4 least significant bits to minimize
; quantisation effects and/or improve resolution. So in this routine the full 16-bit
; value will be used and converted using the following modified transfer function.
;
; Temperature in degC = ((16-bit_ADC_code x 503.975) / (16 x 4096)) - 273.15
;
; Note that only a part of the theoretical temperature range could ever be observed in
; practice (e.g. -40 to +100 for industrial grade devices) so it is of more value to
; preserve the potentially useful resolution than the unused range. As such this routine
; converts the raw status register value into a new 16-bit value which more directly
; relates to degrees centigrade in a practical range.
;
; Hint - Without any form or sample averaging or filtering then the standard 12-bit
; resolution corresponds with 'steps' of 0.123degC . It is useful to recognise
; that this means that die temperature can be known and presented to the nearest
; WHOLE degree using simple rounding. It can also be justified to round
; temperature to the nearest one half of a degree. Note however that that it
; would be inappropriate to represent die temperature using greater numerical
; accuracy than the 0.123degC step size (i.e. a decimal representation using
; more than one decimal place). So just because the converted value produced
; by this routine appears to have greater resolution it should be used with
; due consideration.
;
;
; This routine will take the 16-bit temperature status register value in register pair
; [s9,s8] and convert it to a 16-bit signed value in register pair [s3,s2] representing
; die temperature in degrees centigrade.
;
; A 16x16 bit multiplication routine generating a 32-bit product is used to maintain a
; high degree of precision throughout the conversion process. The 16-bit temperature
; sample is multiplied by a 16-bit constant representing the value 503.975.
;
; 503.975 x 128 = 64508.8 --> 64509 ---> FBFD hex
;
; Then a 32-bit constant representing 273.15 is subtracted.
;
; 273.15 x 128 x 16 x 4096 = 2291348275.2 --> 2291348275 ---> 88933333 hex
;
; The most significant 16-bits of the 32-bit result will then represent temperature in
; degrees centigrade with a signed <9.7> format meaning 9 integer bits and 7 fractional
; bits providing more than adequate range and precision.
;
;
; Example
; 16-bit ADC Code = 9A85 hex (Theoretically +31.045 degC)
;
; 9A85
; x FBFD
; --------
; 98191C71 --> 98191C71
; - 88933333
; --------
; 0F85E93E --> 0F85
;
; 0F85 hex = 3973 --> 3973 / 128 = 31.039 degC
;
; 0F85 hex = 0000111110000101 --> 000011111.0000101 <9.7> format
; 31 and 5/128
;
;
; Operational limits of an industrial grade device
;
; Temp 16-bit Converted Meaning of
; degC ADC Code <9.7> format signed <9.7> value
;
; -40 766E hex EBFF hex -5121/128 = -40.0078 (-40 and 1/128)
; +100 BD8C hex 3200 hex +12800/128 = +100.0 (+100 and 0/128)
;
;
; Registers used s0, s1, s2 ,s3, s4, s5, s6, s7, s8, s9
;
; Provide: [s9,s8] - 16-bit temperature status register value.
; Returns: [s3,s2] - 16-bit signed <9.7> format temperature in degrees centigrade.
;
convert_XADC_temperature: LOAD s5, s9 ;copy original 16-bit sample
LOAD s4, s8
LOAD s7, FB ;16-bit constant representing 503.975
LOAD s6, FD
CALL mult_16x16 ;[s5,s4]x[s7,s6]=[s3,s2,s1,s0]
SUB s0, 33 ;subtract 32-bit constant representing 273.15
SUBCY s1, 33
SUBCY s2, 93
SUBCY s3, 88
RETURN ;[s3,s2] holds signed <9.7> format
;
;
;------------------------------------------------------------------------------------------
; Routine to convert an internal supply sample to a 16-bit milli-Volt integer value
;------------------------------------------------------------------------------------------
;
; Internal supply voltages are associated with the following status registers (obviously
; a supply must have been sampled for the value stored in a register to be valid).
;
; Power Status Registers (Hex addresses)
; Supply Last sample Minimum Maximum
;
; VCCINT 01 25 21
; VCCAUX 02 26 22
; VCCBRAM 06 27 23
;
; VCCPINT 0D 2C 28 (Zynq Only)
; VCCPAUX 0E 2D 29 (Zynq Only)
; VCCO_DDR 0F 2E 2A (Zynq Only)
;
;
; The value obtained when reading a power supply status register is 16-bits. Of these,
; it is the 12 most significant bits which are immediately trustworthy and represent a
; voltage with a theoretical range from 0v to 2.999v. The transfer function for the
; 12-bit sample is...
;
; Voltage = (12-bit_ADC_code / 4096) x 3
;
; However, the use of sample averaging (built-in to XADC when enabled, in the application
; or a combination of both) can exploit the 4 least significant bits to minimize
; quantisation effects and/or improve resolution. So in this routine the full 16-bit
; value will be used and converted using the following modified transfer function.
;
; Voltage = (16-bit_ADC_code / (16 x 4096) ) x 3
;
;
; This routine takes a 16-bit voltage status register value in register pair [s9,s8] and
; converts it to a 16-bit unsigned integer representing voltage rounded to the nearest
; milli-volt (mV). The standard 12-bit resolution corresponds with 'steps' of 0.732mV so
; 1mV resolution is justified and reasonable especially as this routine will maintain
; higher precision throughout the conversion process.
;
; A 16x16 bit multiplication routine generating a 32-bit product is used to scale
; the status register value into a 'milli-volt' value aligned with the upper 16-bits of
; the 32-bit product. Following multiplication, bit15 of the product represents 0.5mV and
; this is used to round the final voltage value before it is returned.
;
;
; Example
; 16-bit ADC Code = 5555 hex (Theoretically 1.000V = 1000mV)
;
; 5555
; x 0BB8 <-- Scaling factor
; --------
; 03E7FC18 --> 03E7 (upper 16-bits of 32-bit product)
; + 1 (most significant bit of FC18 is High >=0.5mv)
; ----
; 03E8 --> 1000mV
;
;
; Registers used s0, s1, s2 ,s3, s4, s5, s6, s7, s8, s9
;
; Provide: [s9,s8] - 16-bit supply voltage status register value.
; Returns: [s3,s2] - 16-bit unsigned voltage in milli-volts (mV).
;
convert_XADC_supply_voltage: LOAD s5, s9 ;copy original 16-bit sample
LOAD s4, s8
LOAD s7, 0B ;16-bit scaling constant
LOAD s6, B8
CALL mult_16x16 ;[s5,s4]x[s7,s6]=[s3,s2,s1,s0]
TEST s1, 10000000'b ;round up to next mV if fraction
ADDCY s2, 00 ; is 0.5mV or more
ADDCY s3, 00
RETURN ;[s3,s2] holds 16-bit mV value
;
;
;------------------------------------------------------------------------------------------
; Routines to convert Unipolar and Bipolar samples to a 16-bit milli-Volt integer value
;------------------------------------------------------------------------------------------
;
; The external analogue inputs are associated with the following status registers.
; Obviously an analogue input must be connected to XADC and that input must have been
; sampled for the value stored in the corresponding status register to be valid.
;
;
; Analogue Status Register
; Input (Hex addresses)
;
; VP/VN 03
; VAUXP[0]/VAUXN[0] 10
; VAUXP[1]/VAUXN[1] 11
; VAUXP[2]/VAUXN[2] 12
; VAUXP[3]/VAUXN[3] 13
; VAUXP[4]/VAUXN[4] 14
; VAUXP[5]/VAUXN[5] 15
; VAUXP[6]/VAUXN[6] 16
; VAUXP[7]/VAUXN[7] 17
; VAUXP[8]/VAUXN[8] 18
; VAUXP[9]/VAUXN[9] 19
; VAUXP[A]/VAUXN[A] 1A
; VAUXP[B]/VAUXN[B] 1B
; VAUXP[C]/VAUXN[C] 1C
; VAUXP[D]/VAUXN[D] 1D
; VAUXP[E]/VAUXN[E] 1E
; VAUXP[F]/VAUXN[F] 1F
;
;
; An input can be configured to be Unipolar with an input voltage range of 0.0v to +1.0v or
; Bipolar with and input range of -0.5v to +0.5v. In each case the total voltage range is
; 1v and the value read from the status register reflects this range. The only difference
; being that the Unipolar value is unsigned and the Bipolar value is a signed using twos
; complement format.
;
; The value obtained when reading one of these status registers is 16-bits. Of these bits,
; it is the 12 most significant bits which are immediately trustworthy and represent a
; voltage with the following transfer function...
;
; Voltage = 12-bit_ADC_code / 4096
;
; However, the use of sample averaging (built-in to XADC when enabled, in the application
; or a combination of both) can exploit the 4 least significant bits to minimize
; quantisation effects and/or improve resolution. So in this routine the full 16-bit
; value will be used and converted using the following modified transfer function.
;
; Voltage = 16-bit_ADC_code / (16 x 4096)
;
; When an input is Unipolar the ADC_code is a 16-bit unsigned value and must be converted
; to represent a voltage in the range 0.0v to +1.0v. When an input is Bipolar the ADC_code
; is a 16-bit signed value (twos complement) and must be converted to represent a voltage
; in the range -0.5v to +0.5v.
;
; 16-bit Unipolar Unipolar Bipolar Bipolar
; ADC_code value voltage value voltage
;
; 0000 0 0v 0 0v
; 7FFF 32767 0.49998v +32767 +0.49998v
; 8000 32768 0.5v -32768 -0.5v
; FFFF 65535 0.99998v -1 -0.0153v
;
; Both the routines provided below take a 16-bit voltage status register value in register
; pair [s9,s8] and convert it to a 16-bit signed integer representing voltage rounded to
; the nearest milli-volt (mV). The standard 12-bit resolution corresponds with 'steps' of
; 244uV so 1mV resolution is justified and reasonable especially as this routine will
; maintain higher precision throughout the conversion process. Note that the effect of
; rounding may result in converted values of 1000mv for Unipolar and +500mV for Bipolar
; even though the theoretical limit of the transfer function falls slightly short of these
; maximum positive levels.
;
; A Unipolar input should result in converted values in the range 0mV to 1000mv which is
; 0000 to 03E8 hex. Since all values are positive the 16-bit value could be considered to
; be an unsigned 16-bit integer. However, it can be useful to think in terms of the
; returned value being a 16-bit signed integer which only has positive values. In this
; way the same signed representation applies to both Unipolar and Bipolar values.
;
; A Bipolar input should result in values in the range -500mV to +500mv which is FE0C to
; 01F4 hex in 16-bit twos complement.
;
; The conversion process employs a 16x16 bit multiplication routine generating a 32-bit
; product which is used to scale the status register value into a 'milli-volt' value
; aligned with the upper 16-bits of the 32-bit product. Following multiplication of a
; positive value, bit15 of the product represents 0.5mV and this is used to round the
; final voltage value before it is returned.
;
; All Unipolar values are positive so the scaling and rounding is straightforward.
; Positive Bipolar values can also be handled in exactly the same way as Unipolar values.
; When a negative Bipolar value needs to be converted it will be complemented to form a
; positive value which can be scaled and rounded in the same way. The scaled and rounded
; result is then complemented to restore the negative polarity to the value. This scheme
; enables most of the code to be reused but also ensures that rounding effects are balanced
; around zero (something which is easy to get wrong when handling twos complement).
;
;
; Unipolar example
;
; 16-bit ADC Code = E666 hex (Theoretically 0.900V = 900mV)
;
; E666
; x 03E8 <-- Scaling factor
; --------
; 0383FE70 --> 0383 (upper 16-bits of 32-bit product)
; + 1 (most significant bit of FE70 High >=0.5mv)
; ----
; 0384 --> 900mV
;
;
; Bipolar example - Positive
;
; 16-bit ADC Code = 6666 hex (Theoretically +0.39999V = +400mV)
;
; Most significant bit of 999A is Low so value is positive and can be converted
; in the same way as a Unipolar value.
;
; 6666
; x 03E8 <-- Scaling factor
; --------
; 018FFE70 --> 018F (upper 16-bits of 32-bit product)
; + 1 (most significant bit of FE70 high >= +0.5mv)
; ----
; 0190 --> +400mV
;
;
; Bipolar example - Negative
;
; 16-bit ADC Code = 999A hex (Theoretically -0.39999V = -400mV)
;
; Most significant bit of 999A is High so value is negative. In this case the value
; is first converted to a positive number whilst remembering that the value is negative.
;
; 999A --> invert all bits --> 6665 --> +1 --> 6666
;
; Convert the positive value in the same way as a Unipolar value.
;
; 6666
; x 03E8 <-- Scaling factor
; --------
; 018FFE70 --> 018F (upper 16-bits of 32-bit product)
; + 1 (most significant bit of FE70 high >= +0.5mv)
; ----
; 0190 --> +400mV
;
; Restore the negative polarity.
;
; 0190 --> invert all bits --> FE6F --> +1 --> FE70
;
; FE70 --> -400mV
;
;
; Unipolar Conversion
; -------------------
;
; Provide: [s9,s8] - 16-bit Unipolar external input status register value.
; Returns: [s3,s2] - 16-bit signed (but only positive) voltage in milli-volts (mV).
;
; Registers used s0, s1, s2 ,s3, s4, s5, s6, s7, s8, s9
;
convert_XADC_unipolar_voltage: LOAD s5, s9 ;copy original 16-bit sample
LOAD s4, s8
LOAD s7, 03 ;16-bit scaling constant
LOAD s6, E8
CALL mult_16x16 ;[s5,s4]x[s7,s6]=[s3,s2,s1,s0]
TEST s1, 10000000'b ;round up to next mV if fraction
ADDCY s2, 00 ; is 0.5mV or more
ADDCY s3, 00
RETURN ;[s3,s2] holds 16-bit mV value
;
;
;
; Bipolar Conversion
; -------------------
;
; Provide: [s9,s8] - 16-bit Unipolar external input status register value.
; Returns: [s3,s2] - 16-bit signed (but only positive) voltage in milli-volts (mV).
;
; Registers used s0, s1, s2 ,s3, s4, s5, s6, s7, s8, s9
;
convert_XADC_bipolar_voltage: TEST s9, 10000000'b ;test sign of sample
JUMP NZ, negative_bipolar
JUMP convert_XADC_unipolar_voltage ;includes return
;
negative_bipolar: XOR s8, FF ;twos complement sample
XOR s9, FF ;to make positive
ADD s8, 01
ADDCY s9, 00
CALL convert_XADC_unipolar_voltage ;scale and round positive value
XOR s2, FF ;twos complement converted value
XOR s3, FF ;to make negative
ADD s2, 01
ADDCY s3, 00
RETURN ;[s3,s2] holds negative 16-bit mV value
;
;
;------------------------------------------------------------------------------------------
; 16-bit x 16-bit Multiplication routine (unsigned)
;------------------------------------------------------------------------------------------
;
; 16-bit input [s5,s4] (contents of [s5,s4] are not changed)
; 16-bit input [s7,s6]
; 32-bit output [s3,s2,s1,s0]
;
mult_16x16: LOAD s8, 16'd ;16-bits to multiply by
LOAD s3, 00 ;clear result
LOAD s2, 00 ;[s1,s0] do not need to be reset
mult_16x16_loop: SR0 s7 ;multiply by LSB to MSB
SRA s6 ;
JUMP NC, shift32
ADD s2, s4 ;add [s5,s4] to upper 16-bits of result
ADDCY s3, s5
shift32: SRA s3 ;shift result right (/2)
SRA s2 ;shift includes any carry from addition
SRA s1
SRA s0
SUB s8, 1'd ;count iterations
JUMP NZ, mult_16x16_loop
RETURN
;
;
;------------------------------------------------------------------------------------------
; End of 'xadc_routines.psm'
;------------------------------------------------------------------------------------------
;

View File

@ -0,0 +1,901 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2012-2013, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; PicoBlaze Reference Design.
;
;
; Ken Chapman - Xilinx Ltd
;
; 6th September 2012 - Initial version.
; 24th September 2012 - Corrections to comments only.
; 1st October 2012 - Read Virtual Switches.
; 3rd January 2013 - Constants to define PicoTerm colours.
; Set Virtual Switches.
; Hide DCS Transactions window.
;
; This file contains routines intended to be used with PicoTerm. Please refer to
; 'PicoTerm_README.txt' for descriptions of PicoTerm features and the control
; sequences used with it. The descriptions below describe the routines and how
; they are implemented.
;
; NOTE - This is not a standalone PSM file. This file should be included in
; an application PSM file from which these routines are then called.
;
; INCLUDE "PicoTerm_routines.psm"
;
; NOTE - If the unique features provided by PicoTerm are to be exploited then
; this file should be used in place of the 'uart_interface_routines.psm'
; file. As described below, the 'UART_RX' routine provided in this file
; contains additions to service the special PicoTerm features when required.
;
;
; Obviously communication with PicoTerm requires the UART macros to be connected to
; KCPSM6 and for PicoTerm to be connected and active. For example the Xilinx KC705
; Evaluation Kit has a USB/UART interface so the USB cable should be connected to
; your PC and PicoTerm connected to the corresponding virtual COM port.
;
; IMPORTANT - This file contains routines to transmit and receive characters to and
; from the UART macros so the CONSTANT directives defined below must be
; set to correspond with your I/O port and scratch pad memory assignments.
;
;
;
; Default PicoTerm Window
; -----------------------
;
; The following three routines provide a simple interface with the UART macros and are
; the only ones that need to be used to receive characters from PicoTerm (e.g. keyboard
; entries) and transmit characters to be displayed in the default PicoTerm window. As
; such they are also suitable for use with any terminal used to display characters and
; facilitate keyboard entries.
;
; reset_UART_macros - Resets the FIFO buffers in both the transmitter and receiver.
;
; UART_TX - This routine will transmit the character provided in register 's5'.
; If the transmitter FIFO buffer is already full then the routine will wait
; for space to become available. Note that this could take up to 86.8us when
; the baud rate is 115,200.
;
; UART_RX - This routine will attempt to receive a character and return it in register
; 's5'. If the receiver FIFO buffer is empty then the routine will wait for
; ~2,000 clock cycles and then timeout (the Zero flag will be set on return
; if timeout occurs). The timeout can be used to prevent KCPSM6 from
; 'hanging' should UART communication fail or no characters be received.
; This routine also intercepts 'Device Control Strings' should they be
; received from PicoTerm (see description below).
;
;
; Escape Sequences
; ----------------
;
; PicoTerm supports 'Escape Sequences' that can clear the default window, position the
; cursor in the 'HOME' position and change the text colour. The following routines
; simply transmit these sequences using the UART_TX routine described above.
;
; PicoTerm_CLS - Clear default window and position cursor to upper-left corner.
;
; PicoTerm_HOME - Position cursor to upper-left corner of default window.
;
; PicoTerm_text_Black - Set subsequent character display to Black (PicoTerm default).
; PicoTerm_text_Red - Set subsequent character display to Red.
; PicoTerm_text_Green - Set subsequent character display to Green.
; PicoTerm_text_Yellow - Set subsequent character display to Yellow.
; PicoTerm_text_Blue - Set subsequent character display to Blue.
; PicoTerm_text_Magenta - Set subsequent character display to Magenta.
; PicoTerm_text_Cyan - Set subsequent character display to Cyan.
; PicoTerm_text_Grey - Set subsequent character display to Grey.
; PicoTerm_text_White - Set subsequent character display to White.
;
;
; Device Control Strings (DCS) Introduction
; -----------------------------------------
;
; The more unique features of PicoTerm are accessed using Device Control Strings (DCS).
; Like an 'Escape Sequence', the DCS require the appropriate sequences to be transmitted
; using the UART_TX routine described above. However, there is also the need to provide
; and/or receive information relating to each DCS sequence so these routines are more
; involved.
;
; There are two fundamental types of DCS used with PicoTerm. One type is only used to
; deliver information to PicoTerm only requiring the transmission of a DCS sequence.
; The 'Virtual 7-Segment Display' is an example of this type. The other type of DCS is
; used to request information from PicoTerm and will result in need to intercept and
; receive the response DCS from PicoTerm. The 'Time Value Sequence' being an example of
; this type.
;
; Receiving DCS responses from PicoTerm
;
; This has the potential to be complicated so is worthy of further description before
; the related routines are describe or used. It is easier to appreciate the potential
; issues with an example in which PicoBlaze wants to know the time and uses the DCS
; 'Time Value Sequence' to obtain this from PicoTerm.
;
; Initially the straightforward task of transmitting the 'DCS, 't', 'ST' characters
; is performed using the 'UART_TX' routine three times. Then we could expect PicoTerm
; to respond with the corresponding DCS consisting of six characters ('DCS', 't', hours,
; minutes, seconds, 'ST') which we would expect the UART receiver macro to receive. It
; would then appear to be a simple case of reading the characters from the receiver
; FIFO using the 'UART_RX' routine six times. Indeed, this could be all that is required
; providing the conditions are suitable. However, we can't guarantee that they will be!
;
; The first potential issue is that it will take time for the request sequence to be
; transmitted and for PicoTerm to respond. Whilst PicoBlaze could wait for this to
; happen, the potential issue is that other characters (e.g. keyboard entries) could be
; received from PicoTerm during that time. These characters together with any others
; already held in the receiver FIFO buffer would need to be read and processed before
; the DCS response can be read.
;
; The solution presented in this file is in the form of an enhanced 'UART_RX' routine
; which will automatically intercept any PicoTerm DCS sequence and store its contents
; in scratch pad memory locations. The main program will call the routine to issue
; the DCS request and then continue processing other information. The only requirement is
; that it must make calls to the 'UART_RX' routine as part of that processing. The calls
; to 'UART_RX' serve two purposes. Firstly, they allow characters prior to the DCS
; response to be read and processed in whatever way is required (i.e. no characters
; are discarded or lost). Secondly, every call made to 'UART_RX' provides it with the
; opportunity to intercept a DCS response from PicoTerm even if it only times out.
;
; When 'UART_RX' receives a 'DCS' character it will continue to read all characters
; and store them in scratch pad memory until the 'ST' character is received. If
; necessary it will wait for all the characters to be sent from PicoTerm and received.
; Having received a DCS response the 'UART_RX' routine will end and return to the
; main program in the same way that it would if it had only attempted to receive and
; return one character in register 's5'. If there is no character in the buffer
; following 'ST' then 'UART_RX' will appear to time out in the usual way.
;
; The main program is responsible for processing the response that is stored in scratch
; pad memory. When 'UART_RX' intercepts a DCS response it will store all characters
; between, but not including, the 'DCS' or 'ST' characters. The first character
; received and stored in scratch pad memory identifies the response.
;
; Hint - Only issue one DCS request to PicoTerm at a time and wait for the response.
; Clear the first scratch pad memory location used to store the response
; before making the request and subsequently monitor this location to
; determine when the response has been received.
;
; CAUTION - Remember that the 'uart_rx6' macro only has a 16 character FIFO buffer and
; that a PicoTerm DCS response will consist of multiple characters (e.g. 14 in
; the case of the 'Date String Sequence'). Frequently calling the 'UART_RX'
; routine following the transmission of a PicoTerm DCS sequence will avoid
; buffer overflow. In this context 'frequently' is relative to the time
; taken for the UART to receive characters so unlikely to be a challenge.
; (i.e. At 115,200 baud it takes 86.8us to receive each character during
; which a PicoBlaze operating at 100MHz could execute 4,340 instructions).
;
;
; The Virtual LED Display
; -----------------------
;
; This is one of the DCS sequences that only requires information to be transmitted to
; PicoTerm. The three bytes of information to be displayed on the virtual LEDs must be
; stored in scratch pad memory locations 'PicoTerm_LEDs_Red', 'PicoTerm_LEDs_Amber' and
; 'PicoTerm_LEDs_Green' before calling this routine.
;
; PicoTerm_LEDs - Drives LEDs with values from scratch pad memory.
;
;
; Virtual 7-Segment Display
; -------------------------
;
; This is also a DCS sequence that only requires information to be transmitted to
; PicoTerm. The four bytes of information to be displayed on the virtual 7-Segement
; display must be must be stored in scratch pad memory locations 'PicoTerm_7seg_digit0',
; 'PicoTerm_7seg_digit1', 'PicoTerm_7seg_digit2' and 'PicoTerm_7seg_digit3' before
; calling this routine.
;
; PicoTerm_7Segment - Drives 7-Segment digits with values from scratch pad memory.
;
; nibble_to_7seg - This routine does not communicate with PicoTerm but is useful
; when preparing the 'digit' segment control bytes.
;
;
;
; Virtual Switches Window
; -----------------------
;
; This is also a DCS sequence that only requires information to be transmitted to
; PicoTerm. The two bytes of information to set the 16 virtual switches must be provided
; in registers 's9' (defining switches[15:8]) and 's8' (defining switches[7:0]) before
; calling this routine.
;
; PicoTerm_set_Switches - Defines setting of the 16 virtual switches.
; First use will open the 'PicoTerm Virtual Switches' window
; (see also 'PicoTerm_read_Switches' below).
;
;
; DCS Requests
; ------------
;
; The following routines transmit the appropriate DCS sequence to request information.
; As described in 'Device Control Strings (DCS) Introduction' above, the PicoTerm
; response will the intercepted during subsequent calls of the 'UART_RX' routine and
; stored in scratch pad memory locations 'PicoTerm_Response0' through to
; 'PicoTerm_Response11'. The response length and hence the number of scratch pad memory
; locations used will depend on the request made. The 'DCS' and 'ST' characters are
; not stored.
;
; PicoTerm_Ping - 'Ping' Request
; PicoTerm_Time_String - Request Time String
; PicoTerm_Time_Value - Request Time Value
; PicoTerm_Date_String - Request Date String
; PicoTerm_Date_Value - Request Date Value
; PicoTerm_read_Switches - Request value of 16 virtual switches
; First use will open the 'PicoTerm Virtual Switches' window.
; (see also 'PicoTerm_set_Switches' above).
; PicoTerm_hide_DCS - Hide and/or suppress the PicoTerm DCS Transactions window.
;
;
; Hint - Use 'Ping' to determine if PicoTerm is connected to PicoBlaze before
; attempting to use any of the PicoTerm features. If another terminal
; is being used then your program could display a message informing the
; user to use PicoTerm or your program could continue in a way that
; only used a normal terminal (i.e. text display).
;
;
;------------------------------------------------------------------------------------------
; Hardware Constants
;------------------------------------------------------------------------------------------
;
; The CONSTANT directives below define the input and output ports assigned to the UART
; macros that typically implement the PicoTerm default baud rate of 115,200. Additional
; constants identify the allocation of signals to bits within a port.
;
;
;
; UART Status
; -----------
;
CONSTANT UART_status_port, 00 ; Read status
CONSTANT UART_Tx_data_present, 00000001'b ; Tx data_present - bit0
CONSTANT UART_Tx_half_full, 00000010'b ; half_full - bit1
CONSTANT UART_Tx_full, 00000100'b ; full - bit2
CONSTANT UART_Rx_data_present, 00001000'b ; Rx data_present - bit3
CONSTANT UART_Rx_half_full, 00010000'b ; half_full - bit4
CONSTANT UART_Rx_full, 00100000'b ; full - bit5
;
; Write data to UART_TX6
; ----------------------
;
CONSTANT UART_TX6_output_port, 01
;
; Read data from UART_RX6
; -----------------------
;
CONSTANT UART_RX6_input_port, 01
;
; Reset UART buffers (Constant Optimised Port)
; --------------------------------------------
;
CONSTANT reset_UART_port, 01
CONSTANT UART_tx_reset, 00000001'b ; uart_tx6 reset - bit0
CONSTANT UART_rx_reset, 00000010'b ; uart_rx6 reset - bit1
CONSTANT UART_reset, 00000011'b ; reset Tx and Rx
CONSTANT UART_operate, 00000000'b ; Tx and Rx free to operate
;
;
;------------------------------------------------------------------------------------------
; Scratch Pad Memory
;------------------------------------------------------------------------------------------
;
; The CONSTANT directives below define the allocation of scratch pad memory locations
; used to store information associated with PicoTerm Device Control Strings (DCS).
;
; Hint - If you do not use certain PicoTerm features then the locations do not need
; to be reserved. If a feature is not used then the corresponding routine can
; also be removed to free program memory.
;
CONSTANT PicoTerm_7seg_digit0, 00 ; 7-Segment Digit 0
CONSTANT PicoTerm_7seg_digit1, 01 ; 7-Segment Digit 1
CONSTANT PicoTerm_7seg_digit2, 02 ; 7-Segment Digit 2
CONSTANT PicoTerm_7seg_digit3, 03 ; 7-Segment Digit 3
;
CONSTANT PicoTerm_LEDs_Red, 04 ; Red LEDs
CONSTANT PicoTerm_LEDs_Amber, 05 ; Amber (yellow) LEDs
CONSTANT PicoTerm_LEDs_Green, 06 ; Green LEDs
;
;
; 12 locations need to be reserved for the longest PicoTerm DCS response. These must
; be in adjacent and ascending locations.
;
CONSTANT PicoTerm_Response0, 07 ;Response identifier
CONSTANT PicoTerm_Response1, 08 ;Response data
CONSTANT PicoTerm_Response2, 09
CONSTANT PicoTerm_Response3, 0A
CONSTANT PicoTerm_Response4, 0B
CONSTANT PicoTerm_Response5, 0C
CONSTANT PicoTerm_Response6, 0D
CONSTANT PicoTerm_Response7, 0E
CONSTANT PicoTerm_Response8, 0F
CONSTANT PicoTerm_Response9, 10
CONSTANT PicoTerm_Response10, 11
CONSTANT PicoTerm_Response11, 12
;
;
;------------------------------------------------------------------------------------------
; Colour Constants
;------------------------------------------------------------------------------------------
;
; The following constants correspond with the colour codes for text and graphics in the
; PicoTerm windows.
;
CONSTANT Black, 30'd
CONSTANT Red, 31'd
CONSTANT Green, 32'd
CONSTANT Yellow, 33'd
CONSTANT Blue, 34'd
CONSTANT Magenta, 35'd
CONSTANT Cyan, 36'd
CONSTANT Grey, 37'd
CONSTANT White, 38'd
;
;
;--------------------------------------------------------------------------------------
; Routine to reset UART Buffers inside 'uart_tx6' and ''uart_rx6'.
;--------------------------------------------------------------------------------------
;
; This routine will generate and apply an active High reset pulse to the FIFO
; buffers in both the transmitter and receiver macros.
;
; Note that the reset signals have been assigned to a constant optimised output port
; so the 'OUTPUTK' instructions are used and no registers contents are affected.
;
; No registers are used.
;
reset_UART_macros: OUTPUTK UART_reset, reset_UART_port
OUTPUTK UART_operate, reset_UART_port
RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to send one character to the UART Transmitter ('uart_tx6').
;--------------------------------------------------------------------------------------
;
; This routine will transmit the character provided in register 's5'.
;
; Before the character is output to the 'UART_TX6' macro the status of the FIFO buffer
; is checked to see if there is space. If the buffer is full then this routine will
; wait for space to become available (e.g. the time required for a previous character
; to be transmitted by the UART).
;
; Registers used s0 and s5 for the data (which is preserved)
;
UART_TX: INPUT s0, UART_status_port ;Check if buffer is full
TEST s0, UART_Tx_full
JUMP NZ, UART_TX ;wait if full
OUTPUT s5, UART_TX6_output_port
RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to attempt to receive one character from the UART Receiver ('uart_rx6').
; Will also intercept a Device Control String from PicoTerm.
;--------------------------------------------------------------------------------------
;
; This routine will attempt to receive one character from the 'UART_RX6' macro, and if
; successful, will return that character in register 's5' with Zero flag reset (Z=0).
;
; If there are no characters available to be read from the FIFO buffer within the
; 'UART_RX6' macro then this routine will timeout after ~2,000 clock cycles (which is
; 20us at 100MHz) with the Zero flag set (Z=1). This timeout scheme ensures that KCPSM6
; cannot become stuck in this routine if no characters are received. If you do want
; KCPSM6 to wait indefinitely for a character to be received then perform a test of
; the Zero flag and repeat the call to this routine as shown in this example...
;
; wait_for_UART_RX: CALL UART_RX
; JUMP Z, wait_for_UART_RX
;
; Each time this routine is called it will also attempt to intercept a Device Control
; String (DCS) coming from PicoTerm. If a 'DCS' character is received then this
; routine will continue to receive characters and store them in scratch pad memory at
; starting at location 'PicoTerm_Response0' until an 'ST' character is received ('DCS'
; and 'ST' are not stored).
;
; Note that once a 'DCS' has been observed the UART_RX routine will wait for the complete
; Device Control String to be received and will not time out.
;
; Once a DCS has been received the routine will attempt to receive and return one
; character in register 's5' or time out in the usual way.
;
;
; Registers used s0, s1 and s5.
;
UART_RX: LOAD s1, 167'd ;Timeout = 167 x (6 instructions x 2 clock cycles)
rx_timeout: INPUT s0, UART_status_port
TEST s0, UART_Rx_data_present ;Z=0 and C=1 when data present
JUMP NZ, read_Rx
SUB s1, 1'd
RETURN Z ;Timeout returns with Z=1 and C=0
JUMP rx_timeout
;
; When character in buffer then read it and test for 'DCS'.
;
read_Rx: INPUT s5, UART_RX6_input_port ;read character from buffer
COMPARE s5, 90 ;test for 'DCS' character
JUMP Z, read_DCS ;If 'DCS' then read string
TEST s0, UART_Rx_data_present ;Z=0 and C=1
RETURN ;return character in 's5'
;
; 'DCS' character is discarded and then all other characters up to 'ST' are stored.
; in scratch pad memory.
;
read_DCS: LOAD s1, PicoTerm_Response0 ;pointer to scratch pad memory
;
;
rx_dcs_character: INPUT s0, UART_status_port ;wait for next character
TEST s0, UART_Rx_data_present
JUMP Z, rx_dcs_character
INPUT s5, UART_RX6_input_port ;read character from buffer
;
; 'ST' is used to terminate the reading of the Device Control String ('ST' is
; not stored in scratch pad memory). On receiving 'ST' the UART_RX routine is
; is restarted to provide the opportunity to return one character or time out
; in the usual way.
;
; Note that 'ST' has the code 9C hex so it cannot occur in any string of normal
; ASCII characters (range 00 to 7F). So when a PicoTerm responds with something like
; a date string there are no issues. However, when PicoTerm responds with 8-bit 'data'
; values rather than 'characters' there would appear to be a potential for the value
; 9C hex occurring as data and result in premature termination of the DCS receiving
; process. Fortunately this situation is avoided because even the data values within
; PicoTerm responses will not have the value 9C hex. i.e. Values related to time and
; date all lie within the range 0 to 99 decimal (00 to 63 hex).
;
COMPARE s5, 9C ;test for 'ST' character
JUMP Z, UART_RX ;If 'ST' then attempt normal receive
;
STORE s5, (s1) ;store character
ADD s1, 1'd ;increment pointer
JUMP rx_dcs_character
;
;
;--------------------------------------------------------------------------------------
; Routine to clear PicoTerm main terminal screen
;--------------------------------------------------------------------------------------
;
; Will clear the PicoTerm main terminal window and move the cursor to the HOME position
; (upper-left corner of window). The text colour is also set to the default of black.
;
; 'ESC' (1B hex = 27)
; '[' (5B hex = 91)
; '2' (32 hex = 50)
; 'J' (4A hex = 74)
;
; Registers used s0 and s5.
;
PicoTerm_CLS: CALL start_escape_sequence
LOAD s5, "2"
CALL UART_TX
LOAD s5, "J"
JUMP UART_TX ;includes RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to move cursor to HOME position
;--------------------------------------------------------------------------------------
;
; Will move the cursor to the HOME position (upper-left corner of window).
;
; 'ESC' (1B hex = 27)
; '[' (5B hex = 91)
; 'H' (48 hex = 72)
;
; Registers used s0 and s5.
;
PicoTerm_HOME: CALL start_escape_sequence
LOAD s5, "H"
JUMP UART_TX ;includes RETURN
;
;
;--------------------------------------------------------------------------------------
; Routines to set the colour of text in the main terminal window
;--------------------------------------------------------------------------------------
;
; These routines will set the colour in which all subsequent text will be displayed
; in the main terminal window. The default colour is black.
;
; 'ESC' (1B hex = 27)
; '[' (5B hex = 91)
; 'n' (Where 'n' defines the colour)
; ( 1E hex = 30 for Black )
; ( 1F hex = 31 for Red )
; ( 20 hex = 32 for Green )
; ( 21 hex = 33 for Yellow )
; ( 22 hex = 34 for Blue )
; ( 23 hex = 35 for Magenta )
; ( 24 hex = 36 for Cyan )
; ( 25 hex = 37 for Grey )
; ( 26 hex = 38 for White )
;
; Registers used s0 and s5.
;
PicoTerm_text_Black: CALL start_escape_sequence
LOAD s5, Black
JUMP UART_TX ;includes RETURN
;
PicoTerm_text_Red: CALL start_escape_sequence
LOAD s5, Red
JUMP UART_TX ;includes RETURN
;
PicoTerm_text_Green: CALL start_escape_sequence
LOAD s5, Green
JUMP UART_TX ;includes RETURN
;
PicoTerm_text_Yellow: CALL start_escape_sequence
LOAD s5, Yellow
JUMP UART_TX ;includes RETURN
;
PicoTerm_text_Blue: CALL start_escape_sequence
LOAD s5, Blue
JUMP UART_TX ;includes RETURN
;
PicoTerm_text_Magenta: CALL start_escape_sequence
LOAD s5, Magenta
JUMP UART_TX ;includes RETURN
;
PicoTerm_text_Cyan: CALL start_escape_sequence
LOAD s5, Cyan
JUMP UART_TX ;includes RETURN
;
PicoTerm_text_Grey: CALL start_escape_sequence
LOAD s5, Grey
JUMP UART_TX ;includes RETURN
;
PicoTerm_text_White: CALL start_escape_sequence
LOAD s5, White
JUMP UART_TX ;includes RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to set the Virtual LED Display
;--------------------------------------------------------------------------------------
;
; This DCS sequence only requires information to be transmitted to PicoTerm and will
; open and set the LEDs of the virtual LED display.
;
; 'DCS'
; 'L'
; RED_control_byte
; YELLOW_control_byte
; GREEN_control_byte
; 'ST'
;
; The three control bytes must be defined in scratch pad memory locations
; 'PicoTerm_LEDs_Red', 'PicoTerm_LEDs_Amber' and 'PicoTerm_LEDs_Green' before
; calling this routine.
;
; Registers used s0 and s5.
;
PicoTerm_LEDs: CALL send_DCS
LOAD s5, "L"
CALL UART_TX
FETCH s5, PicoTerm_LEDs_Red
CALL UART_TX
FETCH s5, PicoTerm_LEDs_Amber
CALL UART_TX
FETCH s5, PicoTerm_LEDs_Green
CALL UART_TX
JUMP send_ST ;includes RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to set the Virtual 7-Segment Display
;--------------------------------------------------------------------------------------
;
; This DCS sequence only requires information to be transmitted to PicoTerm and will
; open and set the segments of the virtual 7-segment display.
;
; 'DCS'
; '7'
; digit0 (segment control byte)
; digit1 (segment control byte)
; digit2 (segment control byte)
; digit3 (segment control byte)
; 'ST'
;
; The four control bytes must be defined in scratch pad memory locations
; 'PicoTerm_7seg_digit0', 'PicoTerm_7seg_digit1', 'PicoTerm_7seg_digit2'
; and 'PicoTerm_7seg_digit3' before calling this routine.
;
; Hint - See 'nibble_to_7seg' routine below.
;
;
; Registers used s0 and s5.
;
PicoTerm_7Segment: CALL send_DCS
LOAD s5, "7"
CALL UART_TX
FETCH s5, PicoTerm_7seg_digit0
CALL UART_TX
FETCH s5, PicoTerm_7seg_digit1
CALL UART_TX
FETCH s5, PicoTerm_7seg_digit2
CALL UART_TX
FETCH s5, PicoTerm_7seg_digit3
CALL UART_TX
JUMP send_ST ;includes RETURN
;
;
;------------------------------------------------------------------------------------------
; Convert 4-bit value to 7-Segment Digit
;------------------------------------------------------------------------------------------
;
; This routine converts the value provided in the lower 4-bits of register s0 into the
; 8-bit code required to drive a 7-Segment digit with the hexadecimal representation.
; The decimal point controlled by bit7 will be off.
;
; Registers used s0, sA and sB
;
nibble_to_7seg: AND s0, 00001111'b ;ensure value provided is only 4-bits
LOAD sB, sevenseg_table'upper ;start of table
LOAD sA, sevenseg_table'lower
ADD sA, s0 ;Add offset to start of table
ADDCY sB, 00
CALL@ (sB, sA) ;Lookup 7-segment control byte from table
RETURN ;control byte returned in s0
;
;
; Conversion Table
;
TABLE 7_segment_decode#, [3F,06,5B,4F,66,6D,7D,07,7F,6F,77,7C,39,5E,79,71]
sevenseg_table: LOAD&RETURN s0, 7_segment_decode#
;
;
;--------------------------------------------------------------------------------------
; Routine to request 'Ping'
;--------------------------------------------------------------------------------------
;
; This DCS sequence will be transmitted and should result in PicoTerm responding with
; a corresponding DCS sequence that will be intercepted by the UART_RX routine and
; stored in scratch pad memory starting at location 'PicoTerm_Response0'.
;
; 'DCS'
; 'p'
; 'ST'
;
; Registers used s0 and s5.
;
PicoTerm_Ping: CALL send_DCS
LOAD s5, "p"
CALL UART_TX
JUMP send_ST ;includes RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to request Time String
;--------------------------------------------------------------------------------------
;
; This DCS sequence will be transmitted and should result in PicoTerm responding with
; a corresponding DCS sequence that will be intercepted by the UART_RX routine and
; stored in scratch pad memory starting at location 'PicoTerm_Response0'.
;
; 'DCS'
; 'T'
; 'ST'
;
; Registers used s0 and s5.
;
PicoTerm_Time_String: CALL send_DCS
LOAD s5, "T"
CALL UART_TX
JUMP send_ST ;includes RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to request Time Value
;--------------------------------------------------------------------------------------
;
; This DCS sequence will be transmitted and should result in PicoTerm responding with
; a corresponding DCS sequence that will be intercepted by the UART_RX routine and
; stored in scratch pad memory starting at location 'PicoTerm_Response0'.
;
; 'DCS'
; 't'
; 'ST'
;
; Registers used s0 and s5.
;
PicoTerm_Time_Value: CALL send_DCS
LOAD s5, "t"
CALL UART_TX
JUMP send_ST ;includes RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to request Date String
;--------------------------------------------------------------------------------------
;
; This DCS sequence will be transmitted and should result in PicoTerm responding with
; a corresponding DCS sequence that will be intercepted by the UART_RX routine and
; stored in scratch pad memory starting at location 'PicoTerm_Response0'.
;
; 'DCS'
; 'D'
; 'ST'
;
; Registers used s0 and s5.
;
PicoTerm_Date_String: CALL send_DCS
LOAD s5, "D"
CALL UART_TX
JUMP send_ST ;includes RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to request Date Value
;--------------------------------------------------------------------------------------
;
; This DCS sequence will be transmitted and should result in PicoTerm responding with
; a corresponding DCS sequence that will be intercepted by the UART_RX routine and
; stored in scratch pad memory starting at location 'PicoTerm_Response0'.
;
; 'DCS'
; 'd'
; 'ST'
;
; Registers used s0 and s5.
;
PicoTerm_Date_Value: CALL send_DCS
LOAD s5, "d"
CALL UART_TX
JUMP send_ST ;includes RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to request current States of Virtual Switches
;--------------------------------------------------------------------------------------
;
; This DCS sequence will be transmitted and should result in PicoTerm responding with
; a corresponding DCS sequence that will be intercepted by the UART_RX routine and
; stored in scratch pad memory starting at location 'PicoTerm_Response0'.
;
; First use of 'PicoTerm_read_Switches' or 'PicoTerm_set_Switches' will also open the
; 'PicoTerm Virtual Switches' window. If this routine is used to open the window then
; all switches will be off ('0').
;
; 'DCS'
; 'S' (note upper case 'S')
; 'ST'
;
; Registers used s0 and s5.
;
PicoTerm_read_Switches: CALL send_DCS
LOAD s5, "S"
CALL UART_TX
JUMP send_ST ;includes RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to set the States of Virtual Switches
;--------------------------------------------------------------------------------------
;
; This DCS sequence will be transmitted and will set the states of the 16 virtual
; switches as defined by the contents of registers [s9,s8]. PicoTerm will not respond
; with a DCS (use 'PicoTerm_read_Switches' to read switch states).
;
; First use of 'PicoTerm_read_Switches' or 'PicoTerm_set_Switches' will also open the
; 'PicoTerm Virtual Switches' window.
;
; 'DCS'
; 's' (note lower case 's')
; switches(0) (new states of switches[7:0] as defined in register 's8')
; switches(1) (new states of switches[15:8]as defined in register 's9')
; 'ST'
;
; Registers used s0, s5, s8 and s9.
;
PicoTerm_set_Switches: CALL send_DCS
LOAD s5, "s"
CALL UART_TX
LOAD s5, s8
CALL UART_TX
LOAD s5, s9
CALL UART_TX
JUMP send_ST ;includes RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to hide and/or suppress the 'PicoTerm DCS Transactions' window.
;--------------------------------------------------------------------------------------
;
; After this DCS sequence has been transmitted, PicoTerm will not open the 'PicoTerm
; DCS Transactions' window and will not display any messages relating to DSC
; sequences. If the 'PicoTerm DCS Transactions' window is already open then it will be
; closed. Suppressing this window can remove a distraction from an end application.
;
; It is strongly recommended that this sequence is only used once an application is
; fully developed and stable because the messages are there to help you see the
; responses to your requests and to see when mistakes have been made.
;
; 'DCS'
; 'h'
; 'ST'
;
; Registers used s0 and s5.
;
PicoTerm_hide_DCS: CALL send_DCS
LOAD s5, "h"
CALL UART_TX
JUMP send_ST ;includes RETURN
;
;
;--------------------------------------------------------------------------------------
; Transmit the start of an Escape Sequence
;--------------------------------------------------------------------------------------
;
; PicoTerm escape sequences all begin with...
;
; 'ESC' (1B hex = 27)
; '[' (5B hex = 91)
;
; Registers used s0 and s5.
;
start_escape_sequence: LOAD s5, ESC
CALL UART_TX
LOAD s5, "["
CALL UART_TX
RETURN
;
;
;--------------------------------------------------------------------------------------
; Routines to transmit 'DCS' and 'ST' characters
;--------------------------------------------------------------------------------------
;
; Registers used s0 and s5.
;
; 'DCS' (90 hex = 144).
;
send_DCS: LOAD s5, DCS
JUMP UART_TX ;includes RETURN
;
; 'ST' (9C hex = 156).
;
send_ST: LOAD s5, ST
JUMP UART_TX ;includes RETURN
;
;
;------------------------------------------------------------------------------------------
; End of 'PicoTerm_routines.psm'
;------------------------------------------------------------------------------------------
;

View File

@ -0,0 +1,880 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2011-2013, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; KCPSM6 reference design: PicoTerm features and UART macros.
;
; Presented on the ATLYS Spartan-6 board but easily ported to other platforms.
;
;
; Ken Chapman - Xilinx Ltd
;
; 6th September 2012 - Initial version
; 26th October 2012 - Correction to comment
; 6th March 2013 - Modified to include PicoTerm Virtual Switches.
; Constant directives defining ASCII control characters removed
; (pre-defined in KCPSM6 assembler v2.43 or later).
;
;
; INTRODUCTION
;
; This program interacts with the 'uart_tx6' and 'uart_rx6' macros to communicate
; with PicoTerm. As well as providing some simple examples of UART based communication
; based on a normal text display and keyboard entry, this program shows some ways in
; which the other features provided by PicoTerm can be used.
;
; NOTE - This design must be used with PicoTerm. The codes does check to see that
; PicoTerm is connected and will display a message and stop if a different
; terminal application is being used.
;
; In particular the design includes a real time digital clock. Hardware generates
; interrupts to KCPSM6 at one second intervals and the interrupt service routine (ISR)
; implements a standard hours, minutes and seconds timer. Two PicoTerm features are
; then used in conjunction with this core functionality. Device Control Strings (DCS)
; pass between KCPSM6 and PicoTerm to synchronised the real time clock to that of
; the connected PC then Virtual 7-Segment Display is used to present the time in a retro
; style (hours and minutes with a flashing point).
;
; With the digital clock serviced by interrupts in KCPSM6 and displayed in a separate
; window by PicoTerm the ability to perform other tasks is also illustrated by a few
; simple functions that again interact with PicoTerm and exploit its features. The
; main PicoTerm window displays text in various colours and then allows characters
; to be typed and displayed. As each character is entered its ASCII code is displayed
; on the Amber row of virtual LEDs in the PicoTerm LEDs window.
;
; The 8 general purpose switches on the board are monitored by KCSPM6 and their settings
; are reflected by the red and green rows of virtual LEDs in the PicoTerm LEDs window.
; In the opposite direction, KCPSM6 monitors the PicoTerm virtual switches and drives
; the 8 real general purpose LEDs on the Atyls board.
;
; Please see 'UART6_User_Guide' for more detailed descriptions of the 'uart_tx6' and
; 'uart_rx6' macros. This document also contains a circuit diagram of the hardware
; design and screen shots of PicoTerm when the design is active. The 'PicoTerm_README'
; file describes how to use PicoTerm as a simple terminal and full details concerning
; its special features and the Device Control Strings (DCS).
;
; NOTE - This PSM file includes two further PSM files so these must also be present
; when running the KCPSM6 assembler. It is hoped that the included files will
; also be suitable for reuse and inclusion in your own programs. For this reason
; each file contains descriptions of the routines that are provided.
;
; PicoTerm_routines.psm - A set of routines to interface with the UART
; macros and use the PicoTerm features.
;
; soft_delays_100mhz.psm - Software delays based on 100MHz clock frequency.
;
;
; The PSM files provided were tested using KCPSM6 Assembler v2.46 and an Atlys board.
;
;
;------------------------------------------------------------------------------------------
; Port definitions
;------------------------------------------------------------------------------------------
;
;
; LEDs and DIP Switches
; ---------------------
;
CONSTANT LED_port, 02 ;8 General purpose LEDs LD[7:0]
;
CONSTANT SWITCH_port, 02 ;8 General purpose Switches SW[7:0]
;
;
; UART (for connection with PicoTerm)
; -----------------------------------
;
; See 'PicoTerm_routines.psm' for I/O ports used with UART macros.
;
;
;------------------------------------------------------------------------------------------
; Special Register usage
;------------------------------------------------------------------------------------------
;
; No registers are given special names in this program.
;
;
;------------------------------------------------------------------------------------------
; Scratch Pad Memory Locations (64 Bytes)
;------------------------------------------------------------------------------------------
;
; Scratch pad memory can be expanded to 128 or 256 bytes if required.
;
;
;
; PicoTerm features
; -----------------
;
; See 'PicoTerm_routines.psm' for allocation of 19 memory locations (00 to 12 hex).
;
;
; Atlys switch values
; -------------------
;
CONSTANT SWITCH_value, 20 ;status of Switches
;
;
; Real time clock
; ---------------
;
CONSTANT seconds, 21
CONSTANT minutes, 22
CONSTANT hours, 23
;
;
;------------------------------------------------------------------------------------------
; Useful data constants
;------------------------------------------------------------------------------------------
;
;
; Real Time Clock
; ---------------
;
CONSTANT seconds_in_a_minute, 60'd
CONSTANT minutes_in_an_hour, 60'd
CONSTANT hours_in_a_day, 24'd
;
;
;------------------------------------------------------------------------------------------
; Initialise the system
;------------------------------------------------------------------------------------------
;
; A delay of 1 second is implemented which is intended to give time for all the hardware
; to settle into a stable condition before starting to doing anything. This can be
; particularly beneficial when dealing with long cables where serial lines can take some
; time to reach the initial idle state following power being applied.
;
cold_start: CALL delay_1s
;
CALL reset_UART_macros ;Reset buffers in UART macros
;
;
; Initialised PicoTerm display and display welcome messages
;
CALL PicoTerm_CLS
CALL welcome_message
;
;
;------------------------------------------------------------------------------------------
; Confirm connection has been made with PicoTerm
;------------------------------------------------------------------------------------------
;
; Before attempting to use any of the special features provided by PicoTerm it is a good
; idea to check that PicoTerm really is connected. This is where the Device Control String
; (DCS) request for a 'Ping' can be used. If a different terminal is being used then the
; plain text messages will be displayed as normal but the 'Ping' request will fail to
; return the response expected. So if this should occur a message will be displayed and
; this program will halt.
;
; Calling the 'PicoTerm_Ping' routine will transmit the Device Control String (DCS)
; to request the 'Ping' from PicoTerm. If PicoTerm is connected then it should respond
; with a DCS containing the (upper case) character 'P'. The response will be intercepted
; by the UART_RX routine and stored in scratch pad memory location 'PicoTerm_Response0'.
; It will take a short while for PicoTerm to respond so the 'Ping' check must wait whilst
; repeatedly calling the UART_RX routine.
;
; The transmission and reception of the 'Ping' DCS sequences (6 characters in total) would
; take ~520us at 115,200 BAUD rate. Since the program is only going to halt if no response
; occurs it will actually wait much longer. Each call of the UART_RX routine that results
; in its timeout will take ~2,000 clock cycles (~20us at 100MHz) so up to 50,000 (C350 hex)
; calls of UART_RX are made before giving up after approximately one second.
;
LOAD s0, 00 ;clear 'Ping' response location
STORE s0, PicoTerm_Response0
;
CALL PicoTerm_Ping ;request 'Ping' from PicoTerm
;
LOAD sB, C3 ;wait for 50,000 iterations
LOAD sA, 50 ; (~1 second at 100MHz)
;
wait_PT_ping: CALL UART_RX ;discard any characters received
FETCH s0, PicoTerm_Response0
COMPARE s0, "P" ;Test for valid 'Ping' response
JUMP Z, PicoTerm_detected ;continue normally
SUB sA, 01 ;decrement [sB,sA]
SUBCY sB, 00
JUMP NZ, wait_PT_ping
;
; 'Ping' response not received so transmit a text message.
; Note this would still be displayed on other terminals.
;
LOAD sB, no_detect_PT_msg'upper
LOAD sA, no_detect_PT_msg'lower
CALL send_message
halt_here: JUMP halt_here ;Halt program.
;
;
STRING not_PT1$, "ERROR - Unable to detect PicoTerm."
STRING not_PT2$, "Please use PicoTerm v1.70 or later with this design."
;
;
no_detect_PT_msg: LOAD&RETURN s5, CR
LOAD&RETURN s5, not_PT1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, not_PT2$
LOAD&RETURN s5, CR
LOAD&RETURN s5, NUL
;
;
;------------------------------------------------------------------------------------------
; PicoTerm text colours
;------------------------------------------------------------------------------------------
;
; A message is displayed in the 8 colours supported by PicoTerm.
;
; This is a simple demonstration of UART communication and the use of Device Control
; Strings (DCS). Please see 'PicoTerm_routines.psm' for the colour setting routines.
;
PicoTerm_detected: CALL send_CR
CALL PicoTerm_text_Red
CALL send_PicoTerm
CALL PicoTerm_text_Green
CALL send_PicoTerm
CALL PicoTerm_text_Yellow
CALL send_PicoTerm
CALL PicoTerm_text_Blue
CALL send_PicoTerm
CALL PicoTerm_text_Magenta
CALL send_PicoTerm
CALL PicoTerm_text_Cyan
CALL send_PicoTerm
CALL PicoTerm_text_Grey
CALL send_PicoTerm
CALL PicoTerm_text_Black
CALL send_PicoTerm
;
; The colour blue will be used for the rest of the program.
;
CALL PicoTerm_text_Blue
;
;
;------------------------------------------------------------------------------------------
; Request time value from PicoTerm and initialise real time clock in scratch pad memory
;------------------------------------------------------------------------------------------
;
; Calling the 'PicoTerm_Time_Value' routine will transmit the Device Control String (DCS)
; to request the time value from PicoTerm. PicoTerm will then respond with a DCS
; containing 't' followed by the time value bytes (hours, minutes and seconds).
;
; Providing the UART_RX routine is being called then it will automatically intercept the
; response from PicoTerm and store it in scratch pad memory. However, it must be
; accepted that the response will take some time to occur and it is possible that other
; characters will be received prior to the response. So for this reason the UART_RX
; routine must be called (potentially multiple times) to enable the response to be
; intercepted and for any other characters to be processed.
;
; In order to determine when the response has been received the first location in which
; the response is stored in scratch pad memory can be used as a 'flag'. Clearing
; location 'PicoTerm_Response0' before requesting the time string allows this location
; to then be monitored. When the contents of this location becomes non zero (in this case
; it would be expected to change to the character 't') then the response is ready to
; be read and used as required.
;
; Note that once UART_RX observes a 'DCS' character indicating the start of a response from
; PicoTerm then it will wait until all of that response has been received and stored in
; scratch pad memory. Hence when the 'flag' location contains 't' it is known that the
; whole DCS response has also been stored in scratch pad memory and is ready to be read.
;
;
LOAD s0, 00 ;clear response 'flag'
STORE s0, PicoTerm_Response0
;
CALL PicoTerm_Time_Value ;request time value from PicoTerm
;
wait_PT_time_value: CALL UART_RX ;discard any other characters received
FETCH s0, PicoTerm_Response0
COMPARE s0, "t" ;Confirm response is the one expected
JUMP NZ, wait_PT_time_value
;
FETCH s0, PicoTerm_Response1 ;initialise hours
STORE s0, hours
FETCH s0, PicoTerm_Response2 ;initialise minutes
STORE s0, minutes
FETCH s0, PicoTerm_Response3 ;initialise seconds
STORE s0, seconds
;
;
;------------------------------------------------------------------------------------------
; Initialise PicoTerm Virtual LED Display
;------------------------------------------------------------------------------------------
;
; The virtual LED's will reflect the settings of the 8 general purpose switches on the
; board and the ASCII code of the last keyboard entry...
;
; Red - Switch is on (up)
; Amber - ASCII code of last keyboard character
; Green - Switch is off (down)
;
;
INPUT s0, SWITCH_port ;read current switch settings
STORE s0, SWITCH_value ;update reference switch setting
;
STORE s0, PicoTerm_LEDs_Red ;pattern for ON switches
XOR s0, 11111111'b ;invert pattern
STORE s0, PicoTerm_LEDs_Green ;pattern for OFF switches
;
LOAD s0, 00000000'b ;Turn off Amber LEDs initially
STORE s0, PicoTerm_LEDs_Amber
;
CALL PicoTerm_LEDs ;open virtual LED window with initial values
;
;
;------------------------------------------------------------------------------------------
; Enable Interrupts for real time clock operation and display
;------------------------------------------------------------------------------------------
;
; Interrupts are generated at 1 second intervals by the hardware. When enabled, interrupts
; force KCPSM6 to execute the interrupt service routine (ISR) which is located at
; address 3C0 (defined by 'interrupt_vector' in the hardware design). Please see the
; 'ISR' located towards the end of this file for the code which implements the real time
; clock presented on the PicoTerm virtual 7-segment display.
;
ENABLE INTERRUPT
;
; Living with interrupts
; ----------------------
;
; Although this reference design and code only appears to do very simple things it is
; intended to show some valuable concepts that should be considered in any design that
; uses interrupts (many applications do not need interrupts at all so in some ways this
; is quite an advanced example even though it appears to be simple).
;
; As you would expect, an interrupt forces KCPSM6 to stop executing the main program and
; jump to the interrupt service routine (ISR). KCPSM6 automatically pushes the current
; address onto its internal stack and preserves the states of the flags such that when
; the ISR completes with a RETURNI instruction the program resumes from the point that it
; was interrupted with the states of the flags automatically restored. The ISR must not
; corrupt critical values held in registers etc but that is straightforward to cover
; (e.g. see use of REGBANK in the ISR contained in this program).
;
; With care, it means that an interrupt can generally be considered to be a totally
; independent section of code. However, it is important in any design to also
; consider how interrupts may affect the main program in other ways even if the
; contents of registers and flags are suitably preserved.
;
; First of all an ISR will take time to execute so consider if that would cause any issues.
; For example, two consecutive OUTPUTK instructions could be used to generate a pulse
; that was intended to have a duration of exactly 2 system clock cycles but if an
; interrupt occurred between them the pulse would be stretched. In this design there
; are no particular issues related to the time to service an interrupt.
;
; The second consideration is if the ISR uses or interacts with anything external
; to KCPSM6 that the main program also uses or interacts with. If it does, then is
; there potential to confuse the external item if the ISR should communicate with the
; external item when the main program has already started interacting with it. In this
; design this is definitely the situation because both the main program and the ISR
; communicate with PicoTerm via the UART. More specifically, the virtual 7-segment
; display, virtual LED display and virtual switches all use Device Control Strings (DCS)
; which involve the transmission of multiple characters to the UART.
;
; The ENABLE INTERRUPT and DISABLE INTERRUPT instructions can be used within the main
; program to temporarily disable interrupts and prevent the ISR from being executed.
; Although this could potentially delay the servicing of an interrupt (so must be used
; with care if an interrupt is truly an 'emergency' situation) it will ensure that
; critical sections of code in the main program will always execute without interruption.
; The pulse generated in the first example above would always have the expected duration.
; In this design the transmission of a DCS from the main program will always be complete.
;
; In the main program that follows there are several places in which interrupts are
; temporarily disabled to ensure that the DCS used to control the virtual LED display and
; virtual switches are never corrupted by the DCS issued by the ISR to control the
; virtual 7-segment display.
;
;
;------------------------------------------------------------------------------------------
; Main Program
;------------------------------------------------------------------------------------------
;
; The 'main' program represents the code area that KCSPM6 will be executing most of the
; time during normal operation (i.e. when not servicing an interrupt). Since the overall
; functionality of this reference design is rather simple the code contained in the
; main program is quite small. However, the considerations given to both interrupts and
; UART are described in detail and it is hoped that these make it a more informative
; reference than initially thought.
;
; The main program maintains UART communication with PicoTerm to detect any keyboard
; entries and display the characters entered back on the PicoTerm terminal. As each
; character is received from the keyboard its ASCII code is displayed on the Amber
; row of virtual LEDs in the PicoTerm LEDs window by transmitting a Device Control String
; (DCS).
;
; The main program also monitors the 8 general purpose switches on the Atlys board
; and sets the red and green rows of virtual LEDs in the PicoTerm LEDs window. In the
; opposite direction, the program invokes and monitors the PicoTerm virtual switches
; and drives the 8 general purpose LEDs on the Atlys board to reflect the settings of
; the lower 8 virtual switches.
;
; In summary, this design and code does illustrates the following independent
; (but apparently simultaneous) functions involving physical hardware and UART
; communications with PicoTerm...
;
; PicoTerm Keyboard -> UART -> KCPSM6 -> UART -> PicoTerm main display
; -> UART -> PicoTerm virtual LEDs (Amber)
;
; Switches on Atlys board -> Input Port -> KCPSM6 -> UART -> PicoTerm virtual LEDs
; (Red/Green)
;
; PicoTerm Virtual Switches -> UART -> KCPSM6 -> Output port -> LEDs on Atlys board
;
; 1-second interrupt -> KCPSM6 -> UART -> PicoTerm virtual 7-Segment display
;
;
; Prompt the user to input characters which will be echoed to the main display and
; their ASCII codes used to set the ambler row of virtual LEDs. This prompt will be
; repeated after the user enters a carriage return (CR).
;
prompt_user: CALL send_CR
CALL send_CR
LOAD sB, prompt_user_msg'upper ;prompt user to enter some characters
LOAD sA, prompt_user_msg'lower
CALL send_message
CALL send_CR
CALL send_CR
LOAD s5, ">"
CALL UART_TX
CALL send_space ;advance cursor ready for user input
;
;
; The Main Loop
; -------------
;
; The main loop will first check to see if the user has entered a character on the
; keyboard (i.e. check UART receiver). It will then read the real switches on the
; Atlys board and compare them with their previous value to see if they have changed.
; Finally, the main loop will check the PicoTerm virtual switches.
;
; When any check encounters activity then the new information is processed.
;
;
; Check keyboard
; --------------
;
; Check to see if the user makes a keyboard entry.
;
; The UART_RX routine (see 'PicoTerm_routines.psm') will wait ~2,000 clock cycles
; (~20us at 100MHz in this design) for a character to be received from the keyboard.
; In addition, it will intercept any DCS received from PicoTerm and store it in
; scratch pad memory (starting at location 'PicoTerm_Response0') and this is used
; to monitor the virtual switches.
;
test_keyboard: CALL UART_RX ;attempt to receive character into s5
JUMP NZ, process_keyboard ;if character has been recieved jump to handling code.
;
;
; Check and process real switches on Atlys board
; ----------------------------------------------
;
; Read the 8 general purpose switches and see if they have changed since the last read.
; If they have changed then update the PicoTerm virtual LEDs reflect their settings by
; transmitting the appropriate Device Control String (DCS).
;
; Red - Switch is on (up)
; Green - Switch is off (down)
;
; Note that a DCS is only transmitted to PicoTerm to change the virtual LEDs when
; either keyboard entry is received or the switches on the Atlys board change. Whilst
; it would be possible to continuously transmit DCS containing the same information it
; is not good practice (e.g. the buffer in the UART transmitter would always be full).
;
INPUT s0, SWITCH_port ;read current switch settings.
FETCH s1, SWITCH_value ;recall previous value
COMPARE s0, s1 ;test for change
JUMP Z, virtual_switches
;
STORE s0, SWITCH_value ;update reference switch settings
STORE s0, PicoTerm_LEDs_Red ;pattern for ON switches
XOR s0, 11111111'b ;invert pattern
STORE s0, PicoTerm_LEDs_Green ;pattern for OFF switches (Amber remains the same)
;
DISABLE INTERRUPT
CALL PicoTerm_LEDs ;update virtual LED window
ENABLE INTERRUPT
;
;
;
; PicoTerm Virtual switches
; -------------------------
;
; The states of the virtual switches are determined by a two part process. Firstly
; a Device Control String (DCS) is transmitted to PicoTerm requesting the switch
; information. Secondly, the DCS response received from PicoTerm must be intercepted
; and processed with the value of the lower 8 virtual switches output to the real
; LEDs on the Atlys board.
;
; Register sE is used as a simple loop counter to reduce the number of times a DCS is
; transmitted to PicoTerm requesting the states of the virtual switches. This ensures
; that the UART communications are not saturated (i.e. FIFO buffer in UART transmitter
; nearly always full). Although the exact frequency that requests are made is not
; critical in this simple reference design it is an interesting exercise to estimate
; the time between requests.
;
; If we assume that no activity is taking place (i.e. no real switch movements, keyboard
; entries or an interrupt) then the main program loop within this program will execute
; just 10 instructions. Every KCPSM6 instruction takes 2 clock cycles to execute so that
; is 20 clock cycles. However, one instruction is a call to the 'UART_RX' routine which
; will deliberately wait for ~2,000 clock cycles before timing out. Hence each iteration
; of the loop will be ~2,020 clock cycles. The loop counter implemented by register 'sE'
; has 256 states so a request will be made every 256 x 2,020 = 517,120 clock cycles. This
; design uses the 100MHz clock on the Atlys board so that means a request is made
; approximately once every 5.17ms. This is ~193 times per second so appears to be immediate
; to the user of PicoTerm but more importantly doesn't saturate the UART communications
; At 115200 BAUD it takes ~86.7us to transfer each character so ~59 characters could be
; transferred in a 5.17ms period and the read virtual switches DCS request only consists
; of 3 characters.
;
;
virtual_switches: ADD sE, 1'd ;increment loop counter
JUMP NC, test_virtual_switches ;did loop counter overflow?
;
DISABLE INTERRUPT
CALL PicoTerm_read_Switches ; DCS request to PicoTerm
ENABLE INTERRUPT
;
; When PicoTerm responds with a DCS containing the states of the virtual switches the
; UART_RX routine will intercept the string and store it in in scratch pad memory starting
; at location 'PicoTerm_Response0'. So this code only has to check when the response has
; been stored in scratch pad memory and then set the real LEDs on the Atlys board (lower
; 8 virtual switches apply only) by writing to the corresponding output port.
;
test_virtual_switches: FETCH s0, PicoTerm_Response0
COMPARE s0, "S" ;test for read virtual switches response
JUMP NZ, test_keyboard
;
FETCH s0, PicoTerm_Response1 ;states of virtual switches [7:0]
OUTPUT s0, LED_port
;
LOAD s0, 00 ;clear DCS response 'flag' so that information
STORE s0, PicoTerm_Response0 ; is only processed once
JUMP test_keyboard
;
;
; Process keyboard entry
; ----------------------
;
; Keyboard entries are echoed back to PicoTerm to be displayed in the main window and
; the ASCII code is sent to PicoTerm to be displayed on the Amber LEDs. If the character
; is a carriage return (CR) then a new prompt is displayed to the user.
;
process_keyboard: CALL UART_TX ;echo user input back to terminal
LOAD sF, s5 ;remember character received
;
STORE s5, PicoTerm_LEDs_Amber ;Set virtual Amber LEDs (Red/Green remain the same)
DISABLE INTERRUPT
CALL PicoTerm_LEDs ;update virtual LED window
ENABLE INTERRUPT
;
COMPARE sF, CR ;was character CR?
JUMP Z, prompt_user
JUMP test_keyboard
;
;
;
;
; Text messages used in main section of the program
;
STRING prompt_user$, "Please type characters which will be echoed to the display and their ASCII codes displayed on PicoTerm's amber LEDs""
;
prompt_user_msg: LOAD&RETURN s5, prompt_user$
LOAD&RETURN s5, NUL
;
;
;------------------------------------------------------------------------------------------
; Welcome Message.
;------------------------------------------------------------------------------------------
;
; The welcome message includes a display of the version information available from the
; assembler and the 'hwbuild' from the instantiation of KCPSM6 in the hardware design.
;
welcome_message: LOAD sB, welcome_msg'upper
LOAD sA, welcome_msg'lower
CALL send_message
HWBUILD s5 ;hardware version defines ASCII letter
CALL UART_TX
CALL send_CR
RETURN
;
; Welcome message
;
STRING banner1$, " _ ______ ____ ____ __ __ __"
STRING banner2$, " | |/ / ___| _ \/ ___|| \/ |/ /_"
STRING banner3$, " | ' / | | |_) \___ \| |\/| | '_ \"
STRING banner4$, " | . \ |___| __/ ___) | | | | (_) )"
STRING banner5$, " |_|\_\____|_| |____/|_| |_|\___/"
;
; Welcome message
;
STRING welcome1$, "Reference Design: UART macros and PicoTerm Features"
STRING welcome2$, " Real Time Clock includes interrupt handling"
STRING welcome3$, "Assembly Date: "
STRING welcome4$, " Time: "
STRING welcome5$, "Assembler Version: "
STRING welcome6$, "Hardware Design: "
;
;
welcome_msg: LOAD&RETURN s5, banner1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner2$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner3$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner4$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner5$
LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome2$
LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome3$
LOAD&RETURN s5, datestamp$
LOAD&RETURN s5, welcome4$
LOAD&RETURN s5, timestamp$
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome5$
LOAD&RETURN s5, KCPSM6_version$
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome6$
LOAD&RETURN s5, NUL
;
;
;
;
;------------------------------------------------------------------------------------------
; Send 'PicoTerm' message
;------------------------------------------------------------------------------------------
;
; Transmit 'PicoTerm can display text in 8 colours!' followed by carriage return.
;
send_PicoTerm: LOAD sB, PicoTerm_msg'upper
LOAD sA, PicoTerm_msg'lower
CALL send_message
RETURN
;
;
STRING PicoTerm$, "PicoTerm can display text in 8 colours!"
;
;
PicoTerm_msg: LOAD&RETURN s5, PicoTerm$
LOAD&RETURN s5, CR
LOAD&RETURN s5, NUL
;
;
;------------------------------------------------------------------------------------------
; Send a message to the UART
;------------------------------------------------------------------------------------------
;
; A message is transmitted to the USB-UART.
; The start address of the message must be provided in [sB,sA].
; Terminate the transmission with a NULL character (00 hex).
;
send_message: CALL@ (sB, sA)
COMPARE s5, 00 ;terminate on NUL character
RETURN Z
CALL UART_TX
ADD sA, 1'd
ADDCY sB, 0'd
JUMP send_message
;
;
;------------------------------------------------------------------------------------------
; Send Carriage Return to UART
;------------------------------------------------------------------------------------------
;
; Registers used s0, s1, s2, and s5.
;
send_CR: LOAD s5, CR
JUMP UART_TX ;includes RETURN
;
;
;------------------------------------------------------------------------------------------
; Send a Space to UART
;------------------------------------------------------------------------------------------
;
; Registers used s0, s1, s2, and s5.
;
send_space: LOAD s5, " "
JUMP UART_TX ;includes RETURN
;
;
;------------------------------------------------------------------------------------------
; Include PSM files
;------------------------------------------------------------------------------------------
;
; The INCLUDE directive enables commonly routines to be kept in their own PSM files and
; easily reused in different programs (i.e. avoiding 'cut and paste'). It also allows
; each PSM to remain a more manageable size.
;
;
; Include routines that implement interface with UART macros and control PicoTerm.
; --------------------------------------------------------------------------------
;
INCLUDE "PicoTerm_routines.psm"
;
;
; Software Delays
; ---------------
;
INCLUDE "soft_delays_100mhz.psm"
;
;
;------------------------------------------------------------------------------------------
; Interrupt Service Routine (ISR) - Real Time Digital Clock
;------------------------------------------------------------------------------------------
;
; The hardware generates an interrupt once per second and this is used to maintain a real
; time clock which is displayed on the PicoTerm Virtual 7-Segment Display.
;
; The real time values of hours, minutes and seconds are held in 3 scratch pad memory
; locations. The ISR reads and increments the seconds value and then writes it back.
; Before writing back a test is made for 60 seconds, and if that is the case, the
; seconds are reset and the process extended to increment the minutes and hours as
; necessary.
;
; Initially the time stored in scratch pad memory will be 00:00:00 but a Device Control
; String (DCS) request to PicoTerm for the time value is used to synchronise the time
; with that of the connected PC. The interrupts and ISR maintain the correct time
; thereafter.
;
; Register Bank 'B' is used during the ISR so that the contents of all registers in Bank
; 'A' used by the main program are preserved. The RETURNI instruction automatically
; restores Bank 'A' on completion of the ISR.
;
; The ISR is located in program memory starting at the location corresponding with
; the 'interrupt_vector' address defined in the instantiation of KCPSM6 in the hardware.
; In this instance the vector is 3C0 hex which means there are 64 instructions available
; before reaching the end of a 1K program memory.
;
ADDRESS 3C0
;
;
ISR: REGBANK B
;
; Update time in scratch pad memory
;
FETCH s0, seconds ;fetch old time
FETCH s1, minutes
FETCH s2, hours
;
ADD s0, 1'd ;increment seconds
COMPARE s0, seconds_in_a_minute ;test for 60 seconds
JUMP Z, update_minutes
STORE s0, seconds ;store new time
JUMP display_time
;
update_minutes: LOAD s0, 0'd ;reset seconds
STORE s0, seconds
ADD s1, 1'd ;increment minutes
COMPARE s1, minutes_in_an_hour ;test for 60 minutes
JUMP Z, update_hours
STORE s1, minutes ;store new time
JUMP display_time
;
update_hours: LOAD s1, 0'd ;reset minutes
STORE s1, minutes
ADD s2, 1'd ;increment hours
COMPARE s2, hours_in_a_day ;test for 24 hours
JUMP Z, clear_hours
STORE s2, hours ;store new time
JUMP display_time
;
clear_hours: LOAD s2, 0'd ;reset hours
STORE s2, hours ;store new time
;
; Display time on PicoTerm Virtual 7-Segment Display.
;
; Hours are in 's2' and Minutes are in 's1'. These binary values are converted
; to decimal and then into 7-segment control codes that are stored in scratch
; pad memory locations before calling the 'PicoTerm_7Segment' routine.
;
; The decimal point of 'digit2' is toggled at 1-second intervals.
;
display_time: SR0 s0 ;isolate LSB of seconds
SRA s3 ; in MSB of s3
AND s3, 10000000'b
;
LOAD s0, s1 ;convert minutes
CALL byte_to_decimal ; to decimal in s1 and s0
CALL nibble_to_7seg ;convert 'units' to 7-seg
STORE s0, PicoTerm_7seg_digit0
LOAD s0, s1 ;convert 'tens' to 7-seg
CALL nibble_to_7seg
STORE s0, PicoTerm_7seg_digit1
;
LOAD s0, s2 ;convert hours
CALL byte_to_decimal ; to decimal in s1 and s0
CALL nibble_to_7seg ;convert 'units' to 7-seg
OR s0, s3 ;superimpose decimal point
STORE s0, PicoTerm_7seg_digit2
LOAD s0, s1 ;convert 'tens' to 7-seg
CALL nibble_to_7seg
STORE s0, PicoTerm_7seg_digit3
;
CALL PicoTerm_7Segment ;PicoTerm display
;
RETURNI ENABLE ;also restores register bank
;
;
;
; Routine to convert binary value in the range 00 to 63 hex provided in register
; 's0' into the binary coded decimal (BCD) equivalent in the range 0 to 99 in
; registers 's1' and 's0'.
;
; Example s0 = 24 hex --> s1 = 3
; 24 hex = 36 decimal s0 = 6
;
;
byte_to_decimal: LOAD s1, 00 ;clear 'tens'
b_to_d_loop: COMPARE s0, 10'd ;if 'units' is less than 10
RETURN C ; then conversion complete
ADD s1, 1'd ;otherwise increment number of 'tens'
SUB s0, 10'd ; and subtract 10 from 'units'
JUMP b_to_d_loop
;
;
;------------------------------------------------------------------------------------------
; End of Program
;------------------------------------------------------------------------------------------
;

View File

@ -0,0 +1,109 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2012-2013, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; PicoBlaze Reference Design.
;
;
; Ken Chapman - Xilinx Ltd
;
; 6th September 2012 - Initial version
; 18th March 2013 - Addition of 20ms delay
;
; This file contains routines that implement delays in software. It should be recognised
; that the delay periods are the result of executing instructions, and because every
; instruction takes 2 clock cycles to execute, it is possible to determine the exact
; delay period. However, besides the obvious dependency on the clock frequency, it
; should also be recognised that any interrupts to KCPSM6 (or use of sleep mode) will
; impact the timing. In general, it is better only to use soft delay routines in
; situations where approximate timing is adequate; in those situations KCPSM6 will often
; exceed your requirements.
;
;
;------------------------------------------------------------------------------------------
; Software Delays based on 100MHz clock
;------------------------------------------------------------------------------------------
;
; The number of iterations of a delay loop required to form each delay required are
; loaded into the register set [s2,s1,s0] and then the delay loop is started.
;
; Registers used s0, s1, s2
;
; 1ms is 10,000 x 100ns (10,000 = 002710 hex)
;
delay_1ms: LOAD s2, 00
LOAD s1, 27
LOAD s0, 10
JUMP software_delay
;
; 20ms is 200,000 x 100ns (200,000 = 030D40 hex)
;
delay_20ms: LOAD s2, 03
LOAD s1, 0D
LOAD s0, 40
JUMP software_delay
;
;
; 1s is 10,000,000 x 100ns (10,000,000 = 989680 hex)
;
delay_1s: LOAD s2, 98
LOAD s1, 96
LOAD s0, 80
JUMP software_delay
;
; The delay loop decrements [s2,s1,s0] until it reaches zero
; Each decrement cycle is 5 instructions which is 10 clock cycles (100ns at 100MHz)
;
software_delay: LOAD s0, s0 ;pad loop to make it 10 clock cycles (5 instructions)
SUB s0, 1'd
SUBCY s1, 0'd
SUBCY s2, 0'd
JUMP NZ, software_delay
RETURN
;
;
;------------------------------------------------------------------------------------------
; End of 'soft_delays_100mhz.psm'
;------------------------------------------------------------------------------------------
;

View File

@ -0,0 +1,126 @@
#
#------------------------------------------------------------------------------------------
# Copyright <20> 2012, Xilinx, Inc.
# This file contains confidential and proprietary information of Xilinx, Inc. and is
# protected under U.S. and international copyright and other intellectual property laws.
#------------------------------------------------------------------------------------------
#
# Disclaimer:
# This disclaimer is not a license and does not grant any rights to the materials
# distributed herewith. Except as otherwise provided in a valid license issued to
# you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
# MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
# DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
# INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
# OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
# (whether in contract or tort, including negligence, or under any other theory
# of liability) for any loss or damage of any kind or nature related to, arising
# under or in connection with these materials, including for any direct, or any
# indirect, special, incidental, or consequential loss or damage (including loss
# of data, profits, goodwill, or any type of loss or damage suffered as a result
# of any action brought by a third party) even if such damage or loss was
# reasonably foreseeable or Xilinx had been advised of the possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-safe, or for use in any
# application requiring fail-safe performance, such as life-support or safety
# devices or systems, Class III medical devices, nuclear facilities, applications
# related to the deployment of airbags, or any other applications that could lead
# to death, personal injury, or severe property or environmental damage
# (individually and collectively, "Critical Applications"). Customer assumes the
# sole risk and liability of any use of Xilinx products in Critical Applications,
# subject only to applicable laws and regulations governing limitations on product
# liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
#
#------------------------------------------------------------------------------------------
#
# Constraints for 'uart6_atlys'.
#
# ATLYS Board (www.digilentinc.com)
#
# XC6SLX45-2CSG324 Device
#
# Ken Chapman - Xilinx Ltd
#
# 6th September 2012 - Initial Release.
#
#
# Timing
# ------
#
# Period constraint for 100MHz operation
#
NET "clk" TNM_NET = "clk";
TIMESPEC TS_kcpsm6_clk = PERIOD "clk" 10.0ns HIGH 50%;
#
#
#
# Pins
# ----
#
# 100MHz Clock.
#
NET "clk" LOC = "L15" | IOSTANDARD = LVCMOS33;
#
# USB-UART
#
NET "uart_rx" LOC = "A16" | IOSTANDARD = LVCMOS33;
NET "uart_tx" LOC = "B16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4;
#
#
# General Purpose LEDs
#
# Note that the LEDs are assigned to different banks and this has resulted
# in a potentially different voltage for LED7.
# LEDs 0, 1, 2, 3, 4, 5 and are always 3.3v
# LEDs 7 is either 2.5v or 3.3v depending on how JP12 is set.
#
NET "led<0>" LOC = "U18" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4;
NET "led<1>" LOC = "M14" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4;
NET "led<2>" LOC = "N14" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4;
NET "led<3>" LOC = "L14" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4;
NET "led<4>" LOC = "M13" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4;
NET "led<5>" LOC = "D4" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4;
NET "led<6>" LOC = "P16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4;
#NET "led<7>" LOC = "N12" | IOSTANDARD = LVCMOS25 | SLEW = SLOW | DRIVE = 4; # 2.5v option
NET "led<7>" LOC = "N12" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4; # 3.3v option
#
#
# General Purpose Switches
#
# Note that the switches are assigned to three different banks and has resulted
# in different voltages....
# Switches 0, 1, 2 and 3 are always 3.3v
# Switches 4, 5 and 6 are either 2.5v or 3.3v depending on how JP12 is set.
# Switches 7 is always 1.8v
#
NET "switch<0>" LOC = "A10" | IOSTANDARD = LVCMOS33;
NET "switch<1>" LOC = "D14" | IOSTANDARD = LVCMOS33;
NET "switch<2>" LOC = "C14" | IOSTANDARD = LVCMOS33;
NET "switch<3>" LOC = "P15" | IOSTANDARD = LVCMOS33;
#
#NET "switch<4>" LOC = "P12" | IOSTANDARD = LVCMOS25; # 2.5v options
#NET "switch<5>" LOC = "R5" | IOSTANDARD = LVCMOS25;
#NET "switch<6>" LOC = "T5" | IOSTANDARD = LVCMOS25;
#
NET "switch<4>" LOC = "P12" | IOSTANDARD = LVCMOS33; # 3.3v options
NET "switch<5>" LOC = "R5" | IOSTANDARD = LVCMOS33;
NET "switch<6>" LOC = "T5" | IOSTANDARD = LVCMOS33;
#
NET "switch<7>" LOC = "E4" | IOSTANDARD = LVCMOS18;
#
#
# RESET Press Button (Active Low)
#
# Note that this button is either 2.5v or 3.3v depending on how JP12 is set.
#
NET "reset_b" LOC = "T15" | IOSTANDARD = LVCMOS33; # 3.3v options
#NET "reset_b" LOC = "T15" | IOSTANDARD = LVCMOS25; # 2.5v options
#
#
#------------------------------------------------------------------------------------------
# End of File
#------------------------------------------------------------------------------------------
#

View File

@ -0,0 +1,434 @@
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2011-2012, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and [2] Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
//
// KCPSM6 reference design using 'uart_tx6' and 'uart_rx6'macros.
//
//
// Target platform - ATLYS Spartan-6 Board (www.digilentinc.com).
// To be used in conjunction with the PicoTerm terminal.
//
//
// Ken Chapman - Xilinx Ltd.
//
// 19th September 2012 - Conversion from original VHDL version (6th September 2012).
//
//
// This reference design primarily provides an example of UART communication. It also
// includes some simple I/O ports (switches and LEDs) together with a simple example of
// a KCPSM6 interrupt. The KCPSM6 program provided with this hardware design demonstrates
// each of these KCPSM6 features together with features of PicoTerm.
//
// Please see 'UART6_User_Guide_30Sept12.pdf' for more descriptions.
//
// The code in this example is set to implement a 115200 UART baud rate and generates
// interrupts at one second intervals based on a 100MHz clock.
//
// Whilst the design is presented as a working example for the XC6SLX45-2CSG324 device on
// the ATLYS Spartan-6 Board (www.digilentinc.com), it is a simple reference design that
// is easily adapted or incorporated into a design for use with any hardware platform.
//
//
//////////////////////////////////////////////////////////////////////////////////////////-
//
//
module uart6_atlys (
input uart_rx,
output uart_tx,
output [7:0] led,
input [7:0] switch,
input reset_b,
input clk );
//
///////////////////////////////////////////////////////////////////////////////////////////
// Signals
///////////////////////////////////////////////////////////////////////////////////////////
//
// Signals used to connect KCPSM6
wire [11:0] address;
wire [17:0] instruction;
wire bram_enable;
reg [7:0] in_port;
wire [7:0] out_port;
wire [7:0] port_id;
wire write_strobe;
wire k_write_strobe;
wire read_strobe;
reg interrupt;
wire interrupt_ack;
wire kcpsm6_sleep;
wire kcpsm6_reset;
wire rdl;
// Signals used to connect UART_TX6
wire [7:0] uart_tx_data_in;
wire write_to_uart_tx;
wire uart_tx_data_present;
wire uart_tx_half_full;
wire uart_tx_full;
reg uart_tx_reset;
// Signals used to connect UART_RX6
wire [7:0] uart_rx_data_out;
reg read_from_uart_rx;
wire uart_rx_data_present;
wire uart_rx_half_full;
wire uart_rx_full;
reg uart_rx_reset;
// Signals used to define baud rate
reg [5:0] baud_count;
reg en_16_x_baud;
// Signals to drive LEDs
reg [7:0] led_port;
// Signals used to generate interrupt at one second intervals
reg [26:0] int_count;
reg event_1hz;
//
//
///////////////////////////////////////////////////////////////////////////////////////////
//
// Start of circuit description
//
///////////////////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////////////////
// Instantiate KCPSM6 and connect to program ROM
/////////////////////////////////////////////////////////////////////////////////////////
//
// The generics can be defined as required. In this case the 'hwbuild' value is used to
// define a version using the ASCII code for the desired letter and the interrupt vector
// has been set to 3C0 to provide 64 instructions for an Interrupt Service Routine (ISR)
// before reaching the end of a 1K memory
//
kcpsm6 #(
.interrupt_vector (12'h3C0),
.scratch_pad_memory_size(64),
.hwbuild (8'h41)) // 41 hex is ASCII Character "A"
processor (
.address (address),
.instruction (instruction),
.bram_enable (bram_enable),
.port_id (port_id),
.write_strobe (write_strobe),
.k_write_strobe (k_write_strobe),
.out_port (out_port),
.read_strobe (read_strobe),
.in_port (in_port),
.interrupt (interrupt),
.interrupt_ack (interrupt_ack),
.reset (kcpsm6_reset),
.sleep (kcpsm6_sleep),
.clk (clk));
// Reset by press button (active Low) or JTAG Loader enabled Program Memory
assign kcpsm6_reset = rdl | ~reset_b;
// Unused signals tied off until required.
// Tying to other signals used to minimise warning messages.
assign kcpsm6_sleep = write_strobe & k_write_strobe; // Always '0'
// Development Program Memory
// JTAG Loader enabled for rapid code development.
atlys_real_time_clock #(
.C_FAMILY ("S6"),
.C_RAM_SIZE_KWORDS (1),
.C_JTAG_LOADER_ENABLE (1))
program_rom (
.rdl (rdl),
.enable (bram_enable),
.address (address),
.instruction (instruction),
.clk (clk));
/////////////////////////////////////////////////////////////////////////////////////////
// Interrupt control
/////////////////////////////////////////////////////////////////////////////////////////
//
// Interrupt is used to provide a 1 second time reference.
//
// A simple binary counter is used to divide the 100MHz clock and provide
// interrupt pulses that remain active until acknowledged by KCPSM6.
//
always @ (posedge clk )
begin
// divide 100MHz by 100,000,000 to form 1Hz pulses
if (int_count == 27'b101111101011110000011111111) begin
int_count <= 27'b000000000000000000000000000;
event_1hz <= 1'b1; // single cycle enable pulse
end
else begin
int_count <= int_count + 27'b000000000000000000000000001;
event_1hz <= 1'b0;
end
// Interrupt becomes active each second and remains active until acknowledged
if (interrupt_ack == 1'b1) begin
interrupt <= 1'b0;
end
else begin
if (event_1hz == 1'b1) begin
interrupt <= 1'b1;
end
else begin
interrupt <= interrupt;
end
end
end
/////////////////////////////////////////////////////////////////////////////////////////
// UART Transmitter with integral 16 byte FIFO buffer
/////////////////////////////////////////////////////////////////////////////////////////
//
// Write to buffer in UART Transmitter at port address 01 hex
//
uart_tx6 tx(
.data_in(uart_tx_data_in),
.en_16_x_baud(en_16_x_baud),
.serial_out(uart_tx),
.buffer_write(write_to_uart_tx),
.buffer_data_present(uart_tx_data_present),
.buffer_half_full(uart_tx_half_full ),
.buffer_full(uart_tx_full),
.buffer_reset(uart_tx_reset),
.clk(clk));
/////////////////////////////////////////////////////////////////////////////////////////
// UART Receiver with integral 16 byte FIFO buffer
/////////////////////////////////////////////////////////////////////////////////////////
//
// Read from buffer in UART Receiver at port address 01 hex.
//
// When KCPMS6 reads data from the receiver a pulse must be generated so that the
// FIFO buffer presents the next character to be read and updates the buffer flags.
//
uart_rx6 rx(
.serial_in(uart_rx),
.en_16_x_baud(en_16_x_baud ),
.data_out(uart_rx_data_out ),
.buffer_read(read_from_uart_rx ),
.buffer_data_present(uart_rx_data_present ),
.buffer_half_full(uart_rx_half_full ),
.buffer_full(uart_rx_full ),
.buffer_reset(uart_rx_reset ),
.clk(clk ));
//
/////////////////////////////////////////////////////////////////////////////////////////
// RS232 (UART) baud rate
/////////////////////////////////////////////////////////////////////////////////////////
//
// To set serial communication baud rate to 115,200 then en_16_x_baud must pulse
// High at 1,843,200Hz which is every 54.28 cycles at 100MHz. In this implementation
// a pulse is generated every 54 cycles resulting is a baud rate of 115,741 baud which
// is only 0.5% high and well within limits.
//
always @ (posedge clk )
begin
if (baud_count == 6'b110101) begin // counts 54 states including zero
baud_count <= 6'b000000;
en_16_x_baud <= 1'b1; // single cycle enable pulse
end
else begin
baud_count <= baud_count + 6'b000001;
en_16_x_baud <= 1'b0;
end
end
//
/////////////////////////////////////////////////////////////////////////////////////////
// General Purpose Input Ports.
/////////////////////////////////////////////////////////////////////////////////////////
//
// Two input ports are used with the UART macros. The first is used to monitor the flags
// on both the UART transmitter and receiver. The second is used to read the data from
// the UART receiver. Note that the read also requires a 'buffer_read' pulse to be
// generated.
//
// This design includes a third input port to read 8 general purpose switches.
//
always @ (posedge clk)
begin
case (port_id[1:0])
// Read UART status at port address 00 hex
2'b00 : in_port <= { 2'b00,
uart_rx_full,
uart_rx_half_full,
uart_rx_data_present,
uart_tx_full,
uart_tx_half_full,
uart_tx_data_present };
// Read UART_RX6 data at port address 01 hex
// (see 'buffer_read' pulse generation below)
2'b01 : in_port <= uart_rx_data_out;
// Read 8 general purpose switches at port address 02 hex
2'b10 : in_port <= switch;
// Don't Care for unused case(s) ensures minimum logic implementation
default : in_port <= 8'bXXXXXXXX ;
endcase;
// Generate 'buffer_read' pulse following read from port address 01
if ((read_strobe == 1'b1) && (port_id[1:0] == 2'b01)) begin
read_from_uart_rx <= 1'b1;
end
else begin
read_from_uart_rx <= 1'b0;
end
end
//
/////////////////////////////////////////////////////////////////////////////////////////
// General Purpose Output Ports
/////////////////////////////////////////////////////////////////////////////////////////
//
// In this simple example there are two output ports.
// A simple output port used to control a set of 8 general purpose LEDs.
// A port used to write data directly to the FIFO buffer within 'uart_tx6' macro.
//
// LEDs are connected to a typical KCPSM6 output port.
// i.e. A register and associated decode logic to enable data capture.
always @ (posedge clk)
begin
// 'write_strobe' is used to qualify all writes to general output ports.
if (write_strobe == 1'b1) begin
// Write to LEDs at port address 02 hex
if (port_id[1] == 1'b1) begin
led_port <= out_port;
end
end
end
// Connect KCPSM6 port to device output pins
assign led = led_port;
// Write directly to the FIFO buffer within 'uart_tx6' macro at port address 01 hex.
// Note the direct connection of 'out_port' to the UART transmitter macro and the
// way that a single clock cycle write pulse is generated to capture the data.
assign uart_tx_data_in = out_port;
assign write_to_uart_tx = write_strobe & port_id[0];
//
/////////////////////////////////////////////////////////////////////////////////////////
// Constant-Optimised Output Ports
/////////////////////////////////////////////////////////////////////////////////////////
//
// One constant-optimised output port is used to facilitate resetting of the UART macros.
//
always @ (posedge clk)
begin
if (k_write_strobe == 1'b1) begin
if (port_id[0] == 1'b1) begin
uart_tx_reset <= out_port[0];
uart_rx_reset <= out_port[1];
end
end
end
/////////////////////////////////////////////////////////////////////////////////////////
endmodule
//
///////////////////////////////////////////////////////////////////////////////////////////
// END OF FILE uart6_atlys.v
///////////////////////////////////////////////////////////////////////////////////////////
//

View File

@ -0,0 +1,536 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2011-2012, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
--
-- KCPSM6 reference design using 'uart_tx6' and 'uart_rx6'macros.
--
-- Target platform - ATLYS Spartan-6 Board (www.digilentinc.com).
-- To be used in conjunction with the PicoTerm terminal.
--
--
-- Ken Chapman - Xilinx Ltd.
--
-- 6th September 2012 - Initial version
--
--
-- This reference design primarily provides an example of UART communication. It also
-- includes some simple I/O ports (switches and LEDs) together with a simple example of
-- a KCPSM6 interrupt. The KCPSM6 program provided with this hardware design demonstrates
-- each of these KCPSM6 features together with features of PicoTerm.
--
-- Please see 'UART6_User_Guide_30Sept12.pdf' for more descriptions.
--
-- The code in this example is set to implement a 115200 UART baud rate and generates
-- interrupts at one second intervals based on a 100MHz clock.
--
-- Whilst the design is presented as a working example for the XC6SLX45-2CSG324 device on
-- the ATLYS Spartan-6 Board (www.digilentinc.com), it is a simple reference design that
-- is easily adapted or incorporated into a design for use with any hardware platform.
--
--
-------------------------------------------------------------------------------------------
--
-- Library declarations
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
--
-------------------------------------------------------------------------------------------
--
--
entity uart6_atlys is
Port ( uart_rx : in std_logic;
uart_tx : out std_logic;
led : out std_logic_vector(7 downto 0);
switch : in std_logic_vector(7 downto 0);
reset_b : in std_logic;
clk : in std_logic);
end uart6_atlys;
--
-------------------------------------------------------------------------------------------
--
-- Start of test architecture
--
architecture Behavioral of uart6_atlys is
--
-------------------------------------------------------------------------------------------
--
-- Components
--
-------------------------------------------------------------------------------------------
--
--
-- declaration of KCPSM6
--
component kcpsm6
generic( hwbuild : std_logic_vector(7 downto 0) := X"00";
interrupt_vector : std_logic_vector(11 downto 0) := X"3FF";
scratch_pad_memory_size : integer := 64);
port ( address : out std_logic_vector(11 downto 0);
instruction : in std_logic_vector(17 downto 0);
bram_enable : out std_logic;
in_port : in std_logic_vector(7 downto 0);
out_port : out std_logic_vector(7 downto 0);
port_id : out std_logic_vector(7 downto 0);
write_strobe : out std_logic;
k_write_strobe : out std_logic;
read_strobe : out std_logic;
interrupt : in std_logic;
interrupt_ack : out std_logic;
sleep : in std_logic;
reset : in std_logic;
clk : in std_logic);
end component;
--
-- Development Program Memory
--
component atlys_real_time_clock
generic( C_FAMILY : string := "S6";
C_RAM_SIZE_KWORDS : integer := 1;
C_JTAG_LOADER_ENABLE : integer := 0);
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
rdl : out std_logic;
clk : in std_logic);
end component;
--
-- UART Transmitter with integral 16 byte FIFO buffer
--
component uart_tx6
Port ( data_in : in std_logic_vector(7 downto 0);
en_16_x_baud : in std_logic;
serial_out : out std_logic;
buffer_write : in std_logic;
buffer_data_present : out std_logic;
buffer_half_full : out std_logic;
buffer_full : out std_logic;
buffer_reset : in std_logic;
clk : in std_logic);
end component;
--
-- UART Receiver with integral 16 byte FIFO buffer
--
component uart_rx6
Port ( serial_in : in std_logic;
en_16_x_baud : in std_logic;
data_out : out std_logic_vector(7 downto 0);
buffer_read : in std_logic;
buffer_data_present : out std_logic;
buffer_half_full : out std_logic;
buffer_full : out std_logic;
buffer_reset : in std_logic;
clk : in std_logic);
end component;
--
--
-------------------------------------------------------------------------------------------
--
-- Signals
--
-------------------------------------------------------------------------------------------
--
--
-- Signals used to connect KCPSM6
--
signal address : std_logic_vector(11 downto 0);
signal instruction : std_logic_vector(17 downto 0);
signal bram_enable : std_logic;
signal in_port : std_logic_vector(7 downto 0);
signal out_port : std_logic_vector(7 downto 0);
signal port_id : std_logic_vector(7 downto 0);
signal write_strobe : std_logic;
signal k_write_strobe : std_logic;
signal read_strobe : std_logic;
signal interrupt : std_logic := '0';
signal interrupt_ack : std_logic;
signal kcpsm6_sleep : std_logic;
signal kcpsm6_reset : std_logic;
signal rdl : std_logic;
--
-- Signals used to connect UART_TX6
--
signal uart_tx_data_in : std_logic_vector(7 downto 0);
signal write_to_uart_tx : std_logic;
signal uart_tx_data_present : std_logic;
signal uart_tx_half_full : std_logic;
signal uart_tx_full : std_logic;
signal uart_tx_reset : std_logic;
--
-- Signals used to connect UART_RX6
--
signal uart_rx_data_out : std_logic_vector(7 downto 0);
signal read_from_uart_rx : std_logic;
signal uart_rx_data_present : std_logic;
signal uart_rx_half_full : std_logic;
signal uart_rx_full : std_logic;
signal uart_rx_reset : std_logic;
--
-- Signals used to define baud rate
--
signal baud_count : integer range 0 to 53 := 0;
signal en_16_x_baud : std_logic := '0';
--
--
-- Signals used to generate interrupt at one second intervals
--
signal int_count : integer range 0 to 99999999 := 0;
signal event_1hz : std_logic := '0';
--
--
-------------------------------------------------------------------------------------------
--
-- Start of circuit description
--
-------------------------------------------------------------------------------------------
--
begin
--
-----------------------------------------------------------------------------------------
-- Instantiate KCPSM6 and connect to program ROM
-----------------------------------------------------------------------------------------
--
-- The generics can be defined as required. In this case the 'hwbuild' value is used to
-- define a version using the ASCII code for the desired letter and the interrupt vector
-- has been set to 3C0 to provide 64 instructions for an Interrupt Service Routine (ISR)
-- before reaching the end of a 1K memory
--
--
processor: kcpsm6
generic map ( hwbuild => X"41", -- 41 hex is ASCII character "A"
interrupt_vector => X"3C0",
scratch_pad_memory_size => 64)
port map( address => address,
instruction => instruction,
bram_enable => bram_enable,
port_id => port_id,
write_strobe => write_strobe,
k_write_strobe => k_write_strobe,
out_port => out_port,
read_strobe => read_strobe,
in_port => in_port,
interrupt => interrupt,
interrupt_ack => interrupt_ack,
sleep => kcpsm6_sleep,
reset => kcpsm6_reset,
clk => clk);
--
-- Reset by press button (active Low) or JTAG Loader enabled Program Memory
--
kcpsm6_reset <= rdl or not(reset_b);
--
-- Unused signals tied off until required.
-- Tying to other signals used to minimise warning messages.
--
kcpsm6_sleep <= write_strobe and k_write_strobe; -- Always '0'
--
-- Development Program Memory
-- JTAG Loader enabled for rapid code development.
--
program_rom: atlys_real_time_clock
generic map( C_FAMILY => "S6",
C_RAM_SIZE_KWORDS => 1,
C_JTAG_LOADER_ENABLE => 1)
port map( address => address,
instruction => instruction,
enable => bram_enable,
rdl => rdl,
clk => clk);
--
-----------------------------------------------------------------------------------------
-- Interrupt control
-----------------------------------------------------------------------------------------
--
-- Interrupt is used to provide a 1 second time reference.
--
-- A simple binary counter is used to divide the 100MHz clock and provide
-- interrupt pulses that remain active until acknowledged by KCPSM6.
--
interrupt_control: process(clk)
begin
if clk'event and clk='1' then
--divide 100MHz by 100,000,000 to form 1Hz pulses
if int_count=99999999 then
int_count <= 0;
event_1hz <= '1';
else
int_count <= int_count + 1;
event_1hz <= '0';
end if;
-- Interrupt becomes active each second and remains active until acknowledged
if interrupt_ack = '1' then
interrupt <= '0';
else
if event_1hz = '1' then
interrupt <= '1';
else
interrupt <= interrupt;
end if;
end if;
end if;
end process interrupt_control;
--
-----------------------------------------------------------------------------------------
-- UART Transmitter with integral 16 byte FIFO buffer
-----------------------------------------------------------------------------------------
--
-- Write to buffer in UART Transmitter at port address 01 hex
--
tx: uart_tx6
port map ( data_in => uart_tx_data_in,
en_16_x_baud => en_16_x_baud,
serial_out => uart_tx,
buffer_write => write_to_uart_tx,
buffer_data_present => uart_tx_data_present,
buffer_half_full => uart_tx_half_full,
buffer_full => uart_tx_full,
buffer_reset => uart_tx_reset,
clk => clk);
--
-----------------------------------------------------------------------------------------
-- UART Receiver with integral 16 byte FIFO buffer
-----------------------------------------------------------------------------------------
--
-- Read from buffer in UART Receiver at port address 01 hex.
--
-- When KCPMS6 reads data from the receiver a pulse must be generated so that the
-- FIFO buffer presents the next character to be read and updates the buffer flags.
--
rx: uart_rx6
port map ( serial_in => uart_rx,
en_16_x_baud => en_16_x_baud,
data_out => uart_rx_data_out,
buffer_read => read_from_uart_rx,
buffer_data_present => uart_rx_data_present,
buffer_half_full => uart_rx_half_full,
buffer_full => uart_rx_full,
buffer_reset => uart_rx_reset,
clk => clk);
--
-----------------------------------------------------------------------------------------
-- RS232 (UART) baud rate
-----------------------------------------------------------------------------------------
--
-- To set serial communication baud rate to 115,200 then en_16_x_baud must pulse
-- High at 1,843,200Hz which is every 54.28 cycles at 100MHz. In this implementation
-- a pulse is generated every 54 cycles resulting is a baud rate of 115,741 baud which
-- is only 0.5% high and well within limits.
--
baud_rate: process(clk)
begin
if clk'event and clk = '1' then
if baud_count = 53 then -- counts 54 states including zero
baud_count <= 0;
en_16_x_baud <= '1'; -- single cycle enable pulse
else
baud_count <= baud_count + 1;
en_16_x_baud <= '0';
end if;
end if;
end process baud_rate;
--
-----------------------------------------------------------------------------------------
-- General Purpose Input Ports.
-----------------------------------------------------------------------------------------
--
-- Two input ports are used with the UART macros. The first is used to monitor the flags
-- on both the UART transmitter and receiver. The second is used to read the data from
-- the UART receiver. Note that the read also requires a 'buffer_read' pulse to be
-- generated.
--
-- This design includes a third input port to read 8 general purpose switches.
--
input_ports: process(clk)
begin
if clk'event and clk = '1' then
case port_id(1 downto 0) is
-- Read UART status at port address 00 hex
when "00" => in_port(0) <= uart_tx_data_present;
in_port(1) <= uart_tx_half_full;
in_port(2) <= uart_tx_full;
in_port(3) <= uart_rx_data_present;
in_port(4) <= uart_rx_half_full;
in_port(5) <= uart_rx_full;
-- Read UART_RX6 data at port address 01 hex
-- (see 'buffer_read' pulse generation below)
when "01" => in_port <= uart_rx_data_out;
-- Read 8 general purpose switches at port address 02 hex
when "10" => in_port <= switch;
-- Don't Care for unused case(s) ensures minimum logic implementation
when others => in_port <= "XXXXXXXX";
end case;
-- Generate 'buffer_read' pulse following read from port address 01
if (read_strobe = '1') and (port_id(1 downto 0) = "01") then
read_from_uart_rx <= '1';
else
read_from_uart_rx <= '0';
end if;
end if;
end process input_ports;
--
-----------------------------------------------------------------------------------------
-- General Purpose Output Ports
-----------------------------------------------------------------------------------------
--
-- In this simple example there are two output ports.
-- A simple output port used to control a set of 8 general purpose LEDs.
-- A port used to write data directly to the FIFO buffer within 'uart_tx6' macro.
--
--
-- LEDs are connected to a typical KCPSM6 output port.
-- i.e. A register and associated decode logic to enable data capture.
--
output_ports: process(clk)
begin
if clk'event and clk = '1' then
-- 'write_strobe' is used to qualify all writes to general output ports.
if write_strobe = '1' then
-- Write to LEDs at port address 02 hex
if port_id(1) = '1' then
led <= out_port;
end if;
end if;
end if;
end process output_ports;
--
-- Write directly to the FIFO buffer within 'uart_tx6' macro at port address 01 hex.
-- Note the direct connection of 'out_port' to the UART transmitter macro and the
-- way that a single clock cycle write pulse is generated to capture the data.
--
uart_tx_data_in <= out_port;
write_to_uart_tx <= '1' when (write_strobe = '1') and (port_id(0) = '1')
else '0';
--
-----------------------------------------------------------------------------------------
-- Constant-Optimised Output Ports
-----------------------------------------------------------------------------------------
--
-- One constant-optimised output port is used to facilitate resetting of the UART macros.
--
constant_output_ports: process(clk)
begin
if clk'event and clk = '1' then
if k_write_strobe = '1' then
if port_id(0) = '1' then
uart_tx_reset <= out_port(0);
uart_rx_reset <= out_port(1);
end if;
end if;
end if;
end process constant_output_ports;
--
-----------------------------------------------------------------------------------------
--
end Behavioral;
-------------------------------------------------------------------------------------------
--
-- END OF FILE uart6_atlys.vhd
--
-------------------------------------------------------------------------------------------

View File

@ -0,0 +1,191 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2014, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
-- A very simple test bench for use with 'uart6_kc705' reference design.
--
-- 25th June 2014
--
-- Ken Chapman
--
-- This test bench will simply provide a clock to the design and enable the KCPSM6 code
-- to be executed and observed. The following simulation only signals can be displayed
-- in the waveforms window to really see what KCPSM6 is doing.
--
-- 'kcpsm6_opcode' - A string displaying the instruction being executed.
-- e.g. "LOAD s7, s4 "
--
-- 'kcpsm6_status' - A string displaying the status of KCPSM6.
-- e.g. "A,NZ,NC,ID,Reset" representing...
-- Register bank 'A' is active.
-- Zero flag is reset (0).
-- Carry flag is reset (0).
-- Interrupts are disabled.
-- Internal reset is active.
--
-- 'sim_s0' through to 'sim_sF'
-- - Contents of registers s0 through to sF.
--
-- 'sim_spm00' through to 'sim_spmFF'
-- - Contents of scratch pad memory locations 00 through to FF.
--
--
-------------------------------------------------------------------------------------------
--
library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-------------------------------------------------------------------------------------------
--
entity testbench_uart6_kc705 is
end testbench_uart6_kc705;
--
-------------------------------------------------------------------------------------------
--
architecture behavior of testbench_uart6_kc705 is
-- Design to be tested
component uart6_kc705
Port ( uart_rx : in std_logic;
uart_tx : out std_logic;
clk200_p : in std_logic;
clk200_n : in std_logic);
end component;
--
-------------------------------------------------------------------------------------------
--
-- Signals to connect to design being tested
--
-- Initial values include the UART receiving a High level which is
-- the normal level for an inactive serial line that is connected.
signal uart_rx : std_logic := '1';
signal uart_tx : std_logic;
signal clk200_p : std_logic := '0';
signal clk200_n : std_logic := '1';
-- Signals used for test purposes only.
signal max_cycles : integer := 5000;
signal cycle_count : integer := 1;
--
-------------------------------------------------------------------------------------------
--
begin
--
-----------------------------------------------------------------------------------------
--
-- Instantiate the design under test
--
-----------------------------------------------------------------------------------------
--
uut: uart6_kc705
port map ( uart_rx => uart_rx,
uart_tx => uart_tx,
clk200_p => clk200_p,
clk200_n => clk200_n);
--
-----------------------------------------------------------------------------------------
--
-- Simulation
--
-----------------------------------------------------------------------------------------
--
-- Simulate a 200MHz differential clock as provided on the KC705 board.
--
-- The test bench simulates for a specified number of clock cycles previously defined by
-- 'max_cycles'. The current clock cycle is defined by 'cycle_count'. In this way the
-- simulation as a pre-defined duration and stimulus can be defined relative to a clock
-- cycles rather than using absolute times.
--
simulate_clock: process
begin
-- Simulate for a specified number of 'cycles'
while cycle_count < max_cycles loop
-- 'clk200_p' starts Low and 'clk200_n' starts High.
-- After 2.5ns the first transition occurs and
-- 'clk200_p' goes High and'clk200_n' goes Low.
wait for 2.5 ns;
clk200_p <= '1';
clk200_n <= '0';
-- After another 2.5ns the second transition occurs and
-- 'clk200_p' returns to Low and 'clk200_n' returns to Low.
wait for 2.5 ns;
clk200_p <= '0';
clk200_n <= '1';
-- This completes once full clock cycle so the cycle counter is incremented.
cycle_count <= cycle_count + 1;
end loop;
wait; -- end of simulation.
end process simulate_clock;
end;
--
-------------------------------------------------------------------------------------------
--
-- End of file 'testbench_uart6_kc705.vhd'.
--
-------------------------------------------------------------------------------------------
--

View File

@ -0,0 +1,94 @@
#
#------------------------------------------------------------------------------------------
# Copyright <20> 2011-2014, Xilinx, Inc.
# This file contains confidential and proprietary information of Xilinx, Inc. and is
# protected under U.S. and international copyright and other intellectual property laws.
#------------------------------------------------------------------------------------------
#
# Disclaimer:
# This disclaimer is not a license and does not grant any rights to the materials
# distributed herewith. Except as otherwise provided in a valid license issued to
# you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
# MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
# DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
# INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
# OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
# (whether in contract or tort, including negligence, or under any other theory
# of liability) for any loss or damage of any kind or nature related to, arising
# under or in connection with these materials, including for any direct, or any
# indirect, special, incidental, or consequential loss or damage (including loss
# of data, profits, goodwill, or any type of loss or damage suffered as a result
# of any action brought by a third party) even if such damage or loss was
# reasonably foreseeable or Xilinx had been advised of the possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-safe, or for use in any
# application requiring fail-safe performance, such as life-support or safety
# devices or systems, Class III medical devices, nuclear facilities, applications
# related to the deployment of airbags, or any other applications that could lead
# to death, personal injury, or severe property or environmental damage
# (individually and collectively, "Critical Applications"). Customer assumes the
# sole risk and liability of any use of Xilinx products in Critical Applications,
# subject only to applicable laws and regulations governing limitations on product
# liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
#
#------------------------------------------------------------------------------------------
#
# Constraints for 'uart6_kc705.vhd'.
#
# KC705 Board Rev.1.1 (www.xilinx.com)
#
# XC7K325T-1FFG900 Device
#
# Ken Chapman - Xilinx Ltd
#
# 23rd June 2014
#
#
#------------------------------------------------------------------------------------------
# Timing Constraints
#------------------------------------------------------------------------------------------
#
#
# Period constraint for 200MHz operation
#
NET "clk" TNM_NET = "clk";
TIMESPEC TS_200MHZ_clk = PERIOD "clk" 5.0ns HIGH 50%;
#
#
#------------------------------------------------------------------------------------------
# Pin Constraints
#------------------------------------------------------------------------------------------
#
#
# 200MHz Differential Clock (SYSCLK).
# -----------------------------------
#
NET "clk200_p" LOC = "AD12" | IOSTANDARD = DIFF_SSTL15;
NET "clk200_n" LOC = "AD11" | IOSTANDARD = DIFF_SSTL15;
#
#
# USB-UART
# --------
#
NET "uart_rx" LOC = "M19" | IOSTANDARD = LVCMOS25;
NET "uart_tx" LOC = "K24" | IOSTANDARD = LVCMOS25 | SLEW = SLOW | DRIVE = 4;
#
#
# CPU_RST (SW7)
# -------------
#
# This input is not used by this design but the constraints have been provided for
# additional reference.
#
# Active High
#
# NET "cpu_rst" LOC = "AB7" | IOSTANDARD = LVCMOS15;
#
#
#------------------------------------------------------------------------------------------
# End of File
#------------------------------------------------------------------------------------------
#

View File

@ -0,0 +1,425 @@
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2011-2014, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and [2] Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
//
// KCPSM6 reference design using 'uart_tx6' and 'uart_rx6'macros.
//
// Ken Chapman - Xilinx Ltd.
//
// 20th June 2014 - Initial version for KC705 board using Vivado 2014.1
//
// This reference design provides a simple UART communication example. Please see
// 'UART6_User_Guide_and_Reference_Designs_30Sept14.pdf' (or later) for more detailed
// descriptions.
//
// The KC705 board provides a 200MHz clock to the Kintex-7 device which is used by all
// circuits in this design including KCPSM6 and the UART macros. In this example, KCPSM6
// computes a constant which is applied to a clock division circuit to define a UART
// communication BAUD rate of 115200.
//
// Whilst the design is presented as a working example for the XC7K325TFFG900-2 device on
// the KC705 Evaluation Board (wwx.xilinx.com), it is a simple reference design that is
// easily adapted or incorporated into a design for use with any hardware platform. Indeed,
// the method presented to define the BAUD rate can make this code even easier to port as
// it only requires one constant to be defined and KCPSM6 works out everything else.
//
//
///////////////////////////////////////////////////////////////////////////////////////////
//
//
module uart6_kc705 ( input uart_rx,
output uart_tx,
input clk200_p,
input clk200_n);
//
///////////////////////////////////////////////////////////////////////////////////////////
// Signals
///////////////////////////////////////////////////////////////////////////////////////////
//
// Signals used to create internal 200MHz clock from 200MHz differential clock
wire clk200;
wire clk;
// Signal used to specify the clock frequency in megahertz.
wire [7:0] clock_frequency_in_MHz;
// Signals used to connect KCPSM6
wire [11:0] address;
wire [17:0] instruction;
wire bram_enable;
reg [7:0] in_port;
wire [7:0] out_port;
wire [7:0] port_id;
wire write_strobe;
wire k_write_strobe;
wire read_strobe;
wire interrupt;
wire interrupt_ack;
wire kcpsm6_sleep;
wire kcpsm6_reset;
wire rdl;
// Signals used to connect UART_TX6
wire [7:0] uart_tx_data_in;
wire write_to_uart_tx;
reg pipe_port_id0;
wire uart_tx_data_present;
wire uart_tx_half_full;
wire uart_tx_full;
reg uart_tx_reset;
// Signals used to connect UART_RX6
wire [7:0] uart_rx_data_out;
reg read_from_uart_rx;
wire uart_rx_data_present;
wire uart_rx_half_full;
wire uart_rx_full;
reg uart_rx_reset;
// Signals used to define baud rate
reg [7:0] set_baud_rate;
reg [7:0] baud_rate_counter;
reg en_16_x_baud;
//
//
///////////////////////////////////////////////////////////////////////////////////////////
//
// Start of circuit description
//
///////////////////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////////////////
// Assign constant value which specifies the clock frequency in megahertz.
/////////////////////////////////////////////////////////////////////////////////////////
assign clock_frequency_in_MHz = 8'd200;
/////////////////////////////////////////////////////////////////////////////////////////
// Create and distribute an internal 200MHz clock from 200MHz differential clock
/////////////////////////////////////////////////////////////////////////////////////////
IBUFGDS diff_clk_buffer(
.I(clk200_p),
.IB(clk200_n),
.O(clk200));
// BUFG used to reach the entire device with 200MHz
BUFG clock_divide (
.I(clk200),
.O(clk));
/////////////////////////////////////////////////////////////////////////////////////////
// Instantiate KCPSM6 and connect to program ROM
/////////////////////////////////////////////////////////////////////////////////////////
//
// The generics can be defined as required. In this case the 'hwbuild' value is used to
// define a version using the ASCII code for the desired letter.
//
kcpsm6 #(
.interrupt_vector (12'h7FF),
.scratch_pad_memory_size(64),
.hwbuild (8'h41)) // 41 hex is ASCII Character "A"
processor (
.address (address),
.instruction (instruction),
.bram_enable (bram_enable),
.port_id (port_id),
.write_strobe (write_strobe),
.k_write_strobe (k_write_strobe),
.out_port (out_port),
.read_strobe (read_strobe),
.in_port (in_port),
.interrupt (interrupt),
.interrupt_ack (interrupt_ack),
.reset (kcpsm6_reset),
.sleep (kcpsm6_sleep),
.clk (clk));
// Reset connected to JTAG Loader enabled Program Memory
assign kcpsm6_reset = rdl;
// Unused signals tied off until required.
// Tying to other signals used to minimise warning messages.
assign kcpsm6_sleep = write_strobe && k_write_strobe; // Always '0'
assign interrupt = interrupt_ack;
// Development Program Memory
// JTAG Loader enabled for rapid code development.
auto_baud_rate_control #(
.C_FAMILY ("7S"),
.C_RAM_SIZE_KWORDS (2),
.C_JTAG_LOADER_ENABLE (1))
program_rom (
.rdl (rdl),
.enable (bram_enable),
.address (address),
.instruction (instruction),
.clk (clk));
/////////////////////////////////////////////////////////////////////////////////////////
// UART Transmitter with integral 16 byte FIFO buffer
/////////////////////////////////////////////////////////////////////////////////////////
//
// Write to buffer in UART Transmitter at port address 01 hex
//
uart_tx6 tx(
.data_in(uart_tx_data_in),
.en_16_x_baud(en_16_x_baud),
.serial_out(uart_tx),
.buffer_write(write_to_uart_tx),
.buffer_data_present(uart_tx_data_present),
.buffer_half_full(uart_tx_half_full ),
.buffer_full(uart_tx_full),
.buffer_reset(uart_tx_reset),
.clk(clk));
/////////////////////////////////////////////////////////////////////////////////////////
// UART Receiver with integral 16 byte FIFO buffer
/////////////////////////////////////////////////////////////////////////////////////////
//
// Read from buffer in UART Receiver at port address 01 hex.
//
// When KCPMS6 reads data from the receiver a pulse must be generated so that the
// FIFO buffer presents the next character to be read and updates the buffer flags.
//
uart_rx6 rx(
.serial_in(uart_rx),
.en_16_x_baud(en_16_x_baud ),
.data_out(uart_rx_data_out ),
.buffer_read(read_from_uart_rx ),
.buffer_data_present(uart_rx_data_present ),
.buffer_half_full(uart_rx_half_full ),
.buffer_full(uart_rx_full ),
.buffer_reset(uart_rx_reset ),
.clk(clk ));
//
/////////////////////////////////////////////////////////////////////////////////////////
// RS232 (UART) baud rate
/////////////////////////////////////////////////////////////////////////////////////////
//
// The baud rate is defined by the frequency of 'en_16_x_baud' pulses. These should occur
// at 16 times the desired baud rate. KCPSM6 computes and sets an 8-bit value into
// 'set_baud_rate' which is used to divide the clock frequency appropriately.
//
// For example, if the clock frequency is 200MHz and the desired serial communication
// baud rate is 115200 then PicoBlaze will set 'set_baud_rate' to 6C hex (108 decimal).
// This circuit will then generate an 'en_16_x_baud' pulse once every 109 clock cycles
// (note that 'baud_rate_counter' will include state zero). This would actually result
// in a baud rate of 114,679 baud but that is only 0.45% low and well within limits.
//
always @ (posedge clk )
begin
if (baud_rate_counter == set_baud_rate) begin
baud_rate_counter <= 5'b00000;
en_16_x_baud <= 1'b1; // single cycle enable pulse
end
else begin
baud_rate_counter <= baud_rate_counter + 5'b00001;
en_16_x_baud <= 1'b0;
end
end
//
/////////////////////////////////////////////////////////////////////////////////////////
// General Purpose Input Ports.
/////////////////////////////////////////////////////////////////////////////////////////
//
// Three input ports are used with the UART macros.
//
// The first is used to monitor the flags on both the transmitter and receiver.
// The second is used to read the data from the receiver and generate a 'buffer_read'
// pulse.
// The third is used to read a user defined constant that enabled KCPSM6 to know the
// clock frequency so that it can compute values which will define the BAUD rate
// for UART communications (as well as values used to define software delays).
//
always @ (posedge clk)
begin
case (port_id[1:0])
// Read UART status at port address 00 hex
2'b00 : in_port <= { 2'b00,
uart_rx_full,
uart_rx_half_full,
uart_rx_data_present,
uart_tx_full,
uart_tx_half_full,
uart_tx_data_present };
// Read UART_RX6 data at port address 01 hex
// (see 'buffer_read' pulse generation below)
2'b01 : in_port <= uart_rx_data_out;
// Read clock frequency contant at port address 02 hex
2'b10 : in_port <= clock_frequency_in_MHz;
// Specify don't care for all other inputs to obtain optimum implementation
default : in_port <= 8'bXXXXXXXX ;
endcase;
// Generate 'buffer_read' pulse following read from port address 01
if ((read_strobe == 1'b1) && (port_id[1:0] == 2'b01)) begin
read_from_uart_rx <= 1'b1;
end
else begin
read_from_uart_rx <= 1'b0;
end
end
//
/////////////////////////////////////////////////////////////////////////////////////////
// General Purpose Output Ports
/////////////////////////////////////////////////////////////////////////////////////////
//
// In this design there are two general purpose output ports.
//
// A port used to write data directly to the FIFO buffer within 'uart_tx6' macro.
//
// A port used to define the communication BAUD rate of the UART.
//
// Note that the assignment and decoding of 'port_id' is a one-hot resulting
// in the minimum number of signals actually being decoded for a fast and
// optimum implementation.
//
always @ (posedge clk)
begin
// 'write_strobe' is used to qualify all writes to general output ports.
if (write_strobe == 1'b1) begin
// Write to UART at port addresses 01 hex
// See below this clocked process for the combinatorial decode required.
// Write to 'set_baud_rate' at port addresses 02 hex
// This value is set by KCPSM6 to define the BAUD rate of the UART.
// See the 'UART baud rate' section for details.
if (port_id[1] == 1'b1) begin
set_baud_rate <= out_port;
end
end
//
// *** To reliably achieve 200MHz performance when writing to the FIFO buffer
// within the UART transmitter, 'port_id' is pipelined to exploit both of
// the clock cycles that it is valid.
//
pipe_port_id0 <= port_id[0];
end
//
// Write directly to the FIFO buffer within 'uart_tx6' macro at port address 01 hex.
// Note the direct connection of 'out_port' to the UART transmitter macro and the
// way that a single clock cycle write pulse is generated to capture the data.
//
assign uart_tx_data_in = out_port;
// See *** above for definition of 'pipe_port_id0'.
assign write_to_uart_tx = write_strobe & pipe_port_id0;
//
/////////////////////////////////////////////////////////////////////////////////////////
// Constant-Optimised Output Ports
/////////////////////////////////////////////////////////////////////////////////////////
//
// One constant-optimised output port is used to facilitate resetting of the UART macros.
//
always @ (posedge clk)
begin
if (k_write_strobe == 1'b1) begin
if (port_id[0] == 1'b1) begin
uart_tx_reset <= out_port[0];
uart_rx_reset <= out_port[1];
end
end
end
/////////////////////////////////////////////////////////////////////////////////////////
endmodule
//
///////////////////////////////////////////////////////////////////////////////////////////
// END OF FILE uart6_kc705.v
///////////////////////////////////////////////////////////////////////////////////////////
//

View File

@ -0,0 +1,543 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2011-2014, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
--
-- KCPSM6 reference design using 'uart_tx6' and 'uart_rx6'macros.
--
-- Ken Chapman - Xilinx Ltd.
--
-- 20th June 2014 - Initial version for KC705 board using Vivado 2014.1
--
-- This reference design provides a simple UART communication example. Please see
-- 'UART6_User_Guide_and_Reference_Designs_30Sept14.pdf' (or later) for more detailed
-- descriptions.
--
-- The KC705 board provides a 200MHz clock to the Kintex-7 device which is used by all
-- circuits in this design including KCPSM6 and the UART macros. In this example, KCPSM6
-- computes a constant which is applied to a clock division circuit to define a UART
-- communication BAUD rate of 115200.
--
-- Whilst the design is presented as a working example for the XC7K325TFFG900-2 device on
-- the KC705 Evaluation Board (www.xilinx.com), it is a simple reference design that is
-- easily adapted or incorporated into a design for use with any hardware platform. Indeed,
-- the method presented to define the BAUD rate can make this code even easier to port as
-- it only requires one constant to be defined and KCPSM6 works out everything else.
--
--
-------------------------------------------------------------------------------------------
--
-- Library declarations
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
-------------------------------------------------------------------------------------------
--
--
entity uart6_kc705 is
Port ( uart_rx : in std_logic;
uart_tx : out std_logic;
clk200_p : in std_logic;
clk200_n : in std_logic);
end uart6_kc705;
--
-------------------------------------------------------------------------------------------
--
-- Start of test architecture
--
architecture Behavioral of uart6_kc705 is
--
-------------------------------------------------------------------------------------------
--
-- Components
--
-------------------------------------------------------------------------------------------
--
--
-- declaration of KCPSM6
--
component kcpsm6
generic( hwbuild : std_logic_vector(7 downto 0) := X"00";
interrupt_vector : std_logic_vector(11 downto 0) := X"3FF";
scratch_pad_memory_size : integer := 64);
port ( address : out std_logic_vector(11 downto 0);
instruction : in std_logic_vector(17 downto 0);
bram_enable : out std_logic;
in_port : in std_logic_vector(7 downto 0);
out_port : out std_logic_vector(7 downto 0);
port_id : out std_logic_vector(7 downto 0);
write_strobe : out std_logic;
k_write_strobe : out std_logic;
read_strobe : out std_logic;
interrupt : in std_logic;
interrupt_ack : out std_logic;
sleep : in std_logic;
reset : in std_logic;
clk : in std_logic);
end component;
--
-- Development Program Memory
--
component auto_baud_rate_control
generic( C_FAMILY : string := "S6";
C_RAM_SIZE_KWORDS : integer := 1;
C_JTAG_LOADER_ENABLE : integer := 0);
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
rdl : out std_logic;
clk : in std_logic);
end component;
--
-- UART Transmitter with integral 16 byte FIFO buffer
--
component uart_tx6
Port ( data_in : in std_logic_vector(7 downto 0);
en_16_x_baud : in std_logic;
serial_out : out std_logic;
buffer_write : in std_logic;
buffer_data_present : out std_logic;
buffer_half_full : out std_logic;
buffer_full : out std_logic;
buffer_reset : in std_logic;
clk : in std_logic);
end component;
--
-- UART Receiver with integral 16 byte FIFO buffer
--
component uart_rx6
Port ( serial_in : in std_logic;
en_16_x_baud : in std_logic;
data_out : out std_logic_vector(7 downto 0);
buffer_read : in std_logic;
buffer_data_present : out std_logic;
buffer_half_full : out std_logic;
buffer_full : out std_logic;
buffer_reset : in std_logic;
clk : in std_logic);
end component;
--
--
-------------------------------------------------------------------------------------------
--
-- Signals
--
-------------------------------------------------------------------------------------------
--
--
-- Signals used to create internal 200MHz clock from 200MHz differential clock
--
signal clk200 : std_logic;
signal clk : std_logic;
--
-- Constant to specify the clock frequency in megahertz.
--
constant clock_frequency_in_MHz : integer range 0 to 255 := 200;
--
--
-- Signals used to connect KCPSM6
--
signal address : std_logic_vector(11 downto 0);
signal instruction : std_logic_vector(17 downto 0);
signal bram_enable : std_logic;
signal in_port : std_logic_vector(7 downto 0);
signal out_port : std_logic_vector(7 downto 0);
signal port_id : std_logic_vector(7 downto 0);
signal write_strobe : std_logic;
signal k_write_strobe : std_logic;
signal read_strobe : std_logic;
signal interrupt : std_logic;
signal interrupt_ack : std_logic;
signal kcpsm6_sleep : std_logic;
signal kcpsm6_reset : std_logic;
signal rdl : std_logic;
--
-- Signals used to connect UART_TX6
--
signal uart_tx_data_in : std_logic_vector(7 downto 0);
signal write_to_uart_tx : std_logic;
signal pipe_port_id0 : std_logic := '0';
signal uart_tx_data_present : std_logic;
signal uart_tx_half_full : std_logic;
signal uart_tx_full : std_logic;
signal uart_tx_reset : std_logic;
--
-- Signals used to connect UART_RX6
--
signal uart_rx_data_out : std_logic_vector(7 downto 0);
signal read_from_uart_rx : std_logic := '0';
signal uart_rx_data_present : std_logic;
signal uart_rx_half_full : std_logic;
signal uart_rx_full : std_logic;
signal uart_rx_reset : std_logic;
--
-- Signals used to define baud rate
--
signal set_baud_rate : std_logic_vector(7 downto 0) := "00000000";
signal baud_rate_counter : std_logic_vector(7 downto 0) := "00000000";
signal en_16_x_baud : std_logic := '0';
--
--
-------------------------------------------------------------------------------------------
--
-- Start of circuit description
--
-------------------------------------------------------------------------------------------
--
begin
--
-----------------------------------------------------------------------------------------
-- Create and distribute an internal 200MHz clock from 200MHz differential clock
-----------------------------------------------------------------------------------------
--
diff_clk_buffer: IBUFGDS
port map ( I => clk200_p,
IB => clk200_n,
O => clk200);
--
-- BUFG used to reach the entire device with 200MHz
--
buffer200: BUFG
port map ( I => clk200,
O => clk);
--
-----------------------------------------------------------------------------------------
-- Instantiate KCPSM6 and connect to program ROM
-----------------------------------------------------------------------------------------
--
-- The generics can be defined as required. In this case the 'hwbuild' value is used to
-- define a version using the ASCII code for the desired letter.
--
processor: kcpsm6
generic map ( hwbuild => X"41", -- 41 hex is ASCII Character "A"
interrupt_vector => X"7FF",
scratch_pad_memory_size => 64)
port map( address => address,
instruction => instruction,
bram_enable => bram_enable,
port_id => port_id,
write_strobe => write_strobe,
k_write_strobe => k_write_strobe,
out_port => out_port,
read_strobe => read_strobe,
in_port => in_port,
interrupt => interrupt,
interrupt_ack => interrupt_ack,
sleep => kcpsm6_sleep,
reset => kcpsm6_reset,
clk => clk);
--
-- Reset connected to JTAG Loader enabled Program Memory
--
kcpsm6_reset <= rdl;
--
-- Unused signals tied off until required.
-- Tying to other signals used to minimise warning messages.
--
kcpsm6_sleep <= write_strobe and k_write_strobe; -- Always '0'
interrupt <= interrupt_ack;
--
-- Development Program Memory
-- JTAG Loader enabled for rapid code development.
--
program_rom: auto_baud_rate_control
generic map( C_FAMILY => "7S",
C_RAM_SIZE_KWORDS => 2,
C_JTAG_LOADER_ENABLE => 1)
port map( address => address,
instruction => instruction,
enable => bram_enable,
rdl => rdl,
clk => clk);
--
-----------------------------------------------------------------------------------------
-- UART Transmitter with integral 16 byte FIFO buffer
-----------------------------------------------------------------------------------------
--
-- Write to buffer in UART Transmitter at port address 01 hex
--
tx: uart_tx6
port map ( data_in => uart_tx_data_in,
en_16_x_baud => en_16_x_baud,
serial_out => uart_tx,
buffer_write => write_to_uart_tx,
buffer_data_present => uart_tx_data_present,
buffer_half_full => uart_tx_half_full,
buffer_full => uart_tx_full,
buffer_reset => uart_tx_reset,
clk => clk);
--
-----------------------------------------------------------------------------------------
-- UART Receiver with integral 16 byte FIFO buffer
-----------------------------------------------------------------------------------------
--
-- Read from buffer in UART Receiver at port address 01 hex.
--
-- When KCPMS6 reads data from the receiver a pulse must be generated so that the
-- FIFO buffer presents the next character to be read and updates the buffer flags.
--
rx: uart_rx6
port map ( serial_in => uart_rx,
en_16_x_baud => en_16_x_baud,
data_out => uart_rx_data_out,
buffer_read => read_from_uart_rx,
buffer_data_present => uart_rx_data_present,
buffer_half_full => uart_rx_half_full,
buffer_full => uart_rx_full,
buffer_reset => uart_rx_reset,
clk => clk);
--
-----------------------------------------------------------------------------------------
-- UART baud rate
-----------------------------------------------------------------------------------------
--
-- The baud rate is defined by the frequency of 'en_16_x_baud' pulses. These should occur
-- at 16 times the desired baud rate. KCPSM6 computes and sets an 8-bit value into
-- 'set_baud_rate' which is used to divide the clock frequency appropriately.
--
-- For example, if the clock frequency is 200MHz and the desired serial communication
-- baud rate is 115200 then PicoBlaze will set 'set_baud_rate' to 6C hex (108 decimal).
-- This circuit will then generate an 'en_16_x_baud' pulse once every 109 clock cycles
-- (note that 'baud_rate_counter' will include state zero). This would actually result
-- in a baud rate of 114,679 baud but that is only 0.45% low and well within limits.
--
baud_rate: process(clk)
begin
if clk'event and clk = '1' then
if baud_rate_counter = set_baud_rate then
baud_rate_counter <= "00000000";
en_16_x_baud <= '1'; -- single cycle enable pulse
else
baud_rate_counter <= baud_rate_counter + 1;
en_16_x_baud <= '0';
end if;
end if;
end process baud_rate;
--
-----------------------------------------------------------------------------------------
-- General Purpose Input Ports.
-----------------------------------------------------------------------------------------
--
-- Three input ports are used with the UART macros.
--
-- The first is used to monitor the flags on both the transmitter and receiver.
-- The second is used to read the data from the receiver and generate a 'buffer_read'
-- pulse.
-- The third is used to read a user defined constant that enabled KCPSM6 to know the
-- clock frequency so that it can compute values which will define the BAUD rate
-- for UART communications (as well as values used to define software delays).
--
input_ports: process(clk)
begin
if clk'event and clk = '1' then
case port_id(1 downto 0) is
-- Read UART status at port address 00 hex
when "00" => in_port(0) <= uart_tx_data_present;
in_port(1) <= uart_tx_half_full;
in_port(2) <= uart_tx_full;
in_port(3) <= uart_rx_data_present;
in_port(4) <= uart_rx_half_full;
in_port(5) <= uart_rx_full;
-- Read UART_RX6 data at port address 01 hex
-- (see 'buffer_read' pulse generation below)
when "01" => in_port <= uart_rx_data_out;
-- Read clock frequency contant at port address 02 hex
when "10" => in_port <= conv_std_logic_vector(clock_frequency_in_MHz, 8);
-- Specify don't care for all other inputs to obtain optimum implementation
when others => in_port <= "XXXXXXXX";
end case;
-- Generate 'buffer_read' pulse following read from port address 01
if (read_strobe = '1') and (port_id(1 downto 0) = "01") then
read_from_uart_rx <= '1';
else
read_from_uart_rx <= '0';
end if;
end if;
end process input_ports;
--
-----------------------------------------------------------------------------------------
-- General Purpose Output Ports
-----------------------------------------------------------------------------------------
--
-- In this design there are two general purpose output ports.
--
-- A port used to write data directly to the FIFO buffer within 'uart_tx6' macro.
--
-- A port used to define the communication BAUD rate of the UART.
--
-- Note that the assignment and decoding of 'port_id' is a one-hot resulting
-- in the minimum number of signals actually being decoded for a fast and
-- optimum implementation.
--
output_ports: process(clk)
begin
if clk'event and clk = '1' then
-- 'write_strobe' is used to qualify all writes to general output ports.
if write_strobe = '1' then
-- Write to UART at port addresses 01 hex
-- See below this clocked process for the combinatorial decode required.
-- Write to 'set_baud_rate' at port addresses 02 hex
-- This value is set by KCPSM6 to define the BAUD rate of the UART.
-- See the 'UART baud rate' section for details.
if (port_id(1) = '1') then
set_baud_rate <= out_port;
end if;
end if;
--
-- *** To reliably achieve 200MHz performance when writing to the FIFO buffer
-- within the UART transmitter, 'port_id' is pipelined to exploit both of
-- the clock cycles that it is valid.
--
pipe_port_id0 <= port_id(0);
end if;
end process output_ports;
--
-- Write directly to the FIFO buffer within 'uart_tx6' macro at port address 01 hex.
-- Note the direct connection of 'out_port' to the UART transmitter macro and the
-- way that a single clock cycle write pulse is generated to capture the data.
--
uart_tx_data_in <= out_port;
-- See *** above for definition of 'pipe_port_id0'.
write_to_uart_tx <= '1' when (write_strobe = '1') and (pipe_port_id0 = '1')
else '0';
--
-----------------------------------------------------------------------------------------
-- Constant-Optimised Output Ports
-----------------------------------------------------------------------------------------
--
-- One constant-optimised output port is used to facilitate resetting of the UART macros.
--
constant_output_ports: process(clk)
begin
if clk'event and clk = '1' then
if k_write_strobe = '1' then
if port_id(0) = '1' then
uart_tx_reset <= out_port(0);
uart_rx_reset <= out_port(1);
end if;
end if;
end if;
end process constant_output_ports;
--
-----------------------------------------------------------------------------------------
--
end Behavioral;
-------------------------------------------------------------------------------------------
--
-- END OF FILE uart6_kc705.vhd
--
-------------------------------------------------------------------------------------------

View File

@ -0,0 +1,146 @@
#
#------------------------------------------------------------------------------------------
# Copyright 2012-2014, Xilinx, Inc.
# This file contains confidential and proprietary information of Xilinx, Inc. and is
# protected under U.S. and international copyright and other intellectual property laws.
#------------------------------------------------------------------------------------------
#
# Disclaimer:
# This disclaimer is not a license and does not grant any rights to the materials
# distributed herewith. Except as otherwise provided in a valid license issued to
# you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
# MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
# DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
# INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
# OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
# (whether in contract or tort, including negligence, or under any other theory
# of liability) for any loss or damage of any kind or nature related to, arising
# under or in connection with these materials, including for any direct, or any
# indirect, special, incidental, or consequential loss or damage (including loss
# of data, profits, goodwill, or any type of loss or damage suffered as a result
# of any action brought by a third party) even if such damage or loss was
# reasonably foreseeable or Xilinx had been advised of the possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-safe, or for use in any
# application requiring fail-safe performance, such as life-support or safety
# devices or systems, Class III medical devices, nuclear facilities, applications
# related to the deployment of airbags, or any other applications that could lead
# to death, personal injury, or severe property or environmental damage
# (individually and collectively, "Critical Applications"). Customer assumes the
# sole risk and liability of any use of Xilinx products in Critical Applications,
# subject only to applicable laws and regulations governing limitations on product
# liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
#
#------------------------------------------------------------------------------------------
#
# Constraints for 'uart6_kc705.vhd'.
#
# KC705 Board (www.xilinx.com) Rev 1.1
#
# XC7K325T-1FFG900 Device
#
# Ken Chapman - Xilinx Ltd
#
# 3rd June 2014
#
#
# DEVICE
# ------
#
# On the KC705 board, bank 0 and the CFGBVS pin are connected to a 2.5v supply.
#
# Configuration voltage supplied to bank 0
# Specified as an actual voltage value
set_property CONFIG_VOLTAGE 2.5 [current_design]
#
# Configuration Bank Voltage Selection (CFGBVS)
# Specified as VCCO (as in this case) or GND
set_property CFGBVS VCCO [current_design]
#
#
# Essential Bits File Generation
# ------------------------------
set_property bitstream.seu.essentialbits yes [current_design]
#
#
# TIMING
# ------
#
# 200MHz clock from oscillator on KC705 board
#
create_clock -period 5 -name clk200 -waveform {0 2.5} -add [get_ports clk200_p]
#
# 200MHz internal clock
#
# create_clock -period 5 -name clk -waveform {0 2.5} -add [get_nets clk]
#
# Signals that appear to be clocks and need to be given a definition to prevent Vivado warnings
#
create_clock -period 100 -name JTAG_Loader_DRCK -waveform {0 10} -add [get_pins program_rom/instantiate_loader.jtag_loader_6_inst/jtag_loader_gen.BSCAN_7SERIES_gen.BSCAN_BLOCK_inst/DRCK]
create_clock -period 1000 -name JTAG_Loader_UPDATE -waveform {0 80} -add [get_pins program_rom/instantiate_loader.jtag_loader_6_inst/jtag_loader_gen.BSCAN_7SERIES_gen.BSCAN_BLOCK_inst/UPDATE]
#
# Tell Vivado to treat all clocks as asynchronous to again prevent unnecessary constraints and warnings.
#
set_clock_groups -name my_async_clocks -asynchronous -group [get_clocks clk200] -group [get_clocks JTAG_Loader_DRCK] -group [get_clocks JTAG_Loader_UPDATE]
#
#
#
# I/O timing is not critical but constraints prevent unnecessary constraints and Vivado warnings.
# Unfortunately Vivado is still reporting 'partial input delay' and 'partial output delay' warnings.
#
#
set_max_delay 50 -from [get_ports uart_rx] -to [get_clocks clk200] -quiet -datapath_only
set_min_delay 0 -from [get_ports uart_rx] -to [get_clocks clk200] -quiet
#set_max_delay 50 -from [get_ports cpu_rst] -to [get_clocks clk200] -quiet -datapath_only
#set_min_delay 0 -from [get_ports cpu_rst] -to [get_clocks clk200] -quiet
#
set_max_delay 50 -from [get_clocks clk200] -to [get_ports uart_tx] -quiet -datapath_only
set_min_delay 0 -from [get_clocks clk200] -to [get_ports uart_tx] -quiet
#
#
#
# DEFINE I/O PINS
# ---------------
#
#
# 200MHz Differential Clock
# -------------------------
#
set_property PACKAGE_PIN AD12 [get_ports clk200_p]
set_property IOSTANDARD DIFF_SSTL15 [get_ports clk200_p]
#
set_property PACKAGE_PIN AD11 [get_ports clk200_n]
set_property IOSTANDARD DIFF_SSTL15 [get_ports clk200_n]
#
#
# USB-UART
# --------
#
set_property PACKAGE_PIN M19 [get_ports uart_rx]
set_property IOSTANDARD LVCMOS25 [get_ports uart_rx]
#
set_property PACKAGE_PIN K24 [get_ports uart_tx]
set_property IOSTANDARD LVCMOS25 [get_ports uart_tx]
set_property SLEW SLOW [get_ports uart_tx]
set_property DRIVE 4 [get_ports uart_tx]
#
#
# CPU_RST press switch (SW7)
# --------------------------
#
# This input is not used by this design but the constraints have been provided for
# additional reference.
#
# Active High
#
# set_property PACKAGE_PIN AB7 [get_ports cpu_rst]
# set_property IOSTANDARD LVCMOS15 [get_ports cpu_rst]
#
#
#------------------------------------------------------------------------------------------
# End of File
#------------------------------------------------------------------------------------------
#

View File

@ -0,0 +1,188 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2011-2012, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; PicoBlaze Reference Design.
;
;
; Ken Chapman - Xilinx Ltd
;
; 23rd April 2012 - Initial Release
; 24th July 2012 - Corrections to comments only
;
; This file contains routines used to interface with the UART6 macros provided with KCPSM6
; and was first supplied with a reference design called 'uart6_605' included in the
; PicoBlaze package. The routines enable characters to be transmitted to and received
; from the UART macros as well as perform a reset of the FIFO the buffers.
;
; NOTE - This is not a standalone PSM file. The 'uart_control.psm' file supplied with
; the reference design stated above includes this file and calls the routines
; contained in this file.
;
; INCLUDE "uart_interface_routines.psm"
;
; Hint - The INCLUDE directive was introduced in KCPSM6 Assembler v2.00.
;
;
; Whilst the reference design stated above was presented for the UART macros connected to
; the USB/UART interface on the Xilinx ML605 Evaluation Kit this file can be ported to
; any design for any board simply by setting the appropriate values in the CONSTANT
; directives described below.
;
;
;------------------------------------------------------------------------------------------
; Hardware Constants
;------------------------------------------------------------------------------------------
;
; The CONSTANT directives below define the input and output ports assigned to the UART
; macros that implement a 115,200 baud rate communication with the USB/UART on the board.
; Additional constants identify the allocation of signals to bits within a port.
;
;
;
; UART Status
; -----------
;
CONSTANT UART_status_port, 00 ; Read status
CONSTANT UART_Tx_data_present, 00000001'b ; Tx data_present - bit0
CONSTANT UART_Tx_half_full, 00000010'b ; half_full - bit1
CONSTANT UART_Tx_full, 00000100'b ; full - bit2
CONSTANT UART_Rx_data_present, 00001000'b ; Rx data_present - bit3
CONSTANT UART_Rx_half_full, 00010000'b ; half_full - bit4
CONSTANT UART_Rx_full, 00100000'b ; full - bit5
;
; Write data to UART_TX6
; ----------------------
;
CONSTANT UART_TX6_output_port, 01
;
; Read data from UART_RX6
; -----------------------
;
CONSTANT UART_RX6_input_port, 01
;
; Reset UART buffers (Constant Optimised Port)
; --------------------------------------------
;
CONSTANT reset_UART_port, 01
CONSTANT UART_tx_reset, 00000001'b ; uart_tx6 reset - bit0
CONSTANT UART_rx_reset, 00000010'b ; uart_rx6 reset - bit1
CONSTANT UART_reset, 00000011'b ; reset Tx and Rx
CONSTANT UART_operate, 00000000'b ; Tx and Rx free to operate
;
;
;--------------------------------------------------------------------------------------
; Routine to reset UART Buffers inside 'uart_tx6' and 'uart_rx6'
;--------------------------------------------------------------------------------------
;
; This routine will generate and apply an active High reset pulse to the FIFO
; buffers in both the transmitter and receiver macros.
;
; Note that the reset signals have been assigned to a constant optimised output port
; so the 'OUTPUTK' instructions are used and no registers contents are affected.
;
;
reset_UART_macros: OUTPUTK UART_reset, reset_UART_port
OUTPUTK UART_operate, reset_UART_port
RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to send one character to the UART Transmitter 'uart_tx6'
;--------------------------------------------------------------------------------------
;
; This routine will transmit the character provided in register 's5'.
;
; Before the character is output to the 'UART_TX6' macro the status of the FIFO buffer
; is checked to see if there is space. If the buffer is full then this routine will
; wait for space to become available (e.g. the time required for a previous character
; to be transmitted by the UART).
;
; Registers used s0 and s5 for the data (which is preserved)
;
UART_TX: INPUT s0, UART_status_port ;Check if buffer is full
TEST s0, UART_Tx_full
JUMP NZ, UART_TX ;wait if full
OUTPUT s5, UART_TX6_output_port
RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to attempt to receive one character from the UART Receiver 'uart_rx6'
;--------------------------------------------------------------------------------------
;
; This routine will attempt to receive one character from the 'UART_RX6' macro, and if
; successful, will return that character in register 's5' and the Zero flag will be
; reset (Z=0).
;
; If there are no characters available to be read from the FIFO buffer within the
; 'UART_RX6' macro then this routine will timeout after ~2,000 clock cycles (which is
; 40us at 50MHz) with the Zero flag set (Z=1). This timeout scheme ensures that KCPSM6
; cannot become stuck in this routine if no characters are received. If you do want
; KCPSM6 to wait indefinitely for a character to be received then either modify this
; routine or perform a test of the Zero flag and repeat the call to this routine as
; shown in this example...
;
; wait_for_UART_RX: CALL UART_RX
; JUMP Z, wait_for_UART_RX
;
;
; Registers used s0, s1 and s5.
;
UART_RX: LOAD s1, 167'd ;Timeout = 167 x (6 instructions x 2 clock cycles)
rx_timeout: INPUT s0, UART_status_port
TEST s0, UART_Rx_data_present ;Z=0 and C=1 when data present
JUMP NZ, read_Rx
SUB s1, 1'd
RETURN Z ;Timeout returns with Z=1 and C=0
JUMP rx_timeout
;
read_Rx: INPUT s5, UART_RX6_input_port ;read character from buffer
RETURN
;
;
;------------------------------------------------------------------------------------------
; End of 'uart_interface_routines.psm"'
;------------------------------------------------------------------------------------------
;

View File

@ -0,0 +1,75 @@
#
#------------------------------------------------------------------------------------------
# Copyright <20> 2011, Xilinx, Inc.
# This file contains confidential and proprietary information of Xilinx, Inc. and is
# protected under U.S. and international copyright and other intellectual property laws.
#------------------------------------------------------------------------------------------
#
# Disclaimer:
# This disclaimer is not a license and does not grant any rights to the materials
# distributed herewith. Except as otherwise provided in a valid license issued to
# you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
# MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
# DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
# INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
# OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
# (whether in contract or tort, including negligence, or under any other theory
# of liability) for any loss or damage of any kind or nature related to, arising
# under or in connection with these materials, including for any direct, or any
# indirect, special, incidental, or consequential loss or damage (including loss
# of data, profits, goodwill, or any type of loss or damage suffered as a result
# of any action brought by a third party) even if such damage or loss was
# reasonably foreseeable or Xilinx had been advised of the possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-safe, or for use in any
# application requiring fail-safe performance, such as life-support or safety
# devices or systems, Class III medical devices, nuclear facilities, applications
# related to the deployment of airbags, or any other applications that could lead
# to death, personal injury, or severe property or environmental damage
# (individually and collectively, "Critical Applications"). Customer assumes the
# sole risk and liability of any use of Xilinx products in Critical Applications,
# subject only to applicable laws and regulations governing limitations on product
# liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
#
#------------------------------------------------------------------------------------------
#
# Constraints for 'uart6_ml605'.
#
# ML605 Board (www.xilinx.com)
#
# XC6VLX240T-1FF1156 Device
#
# Ken Chapman - Xilinx Ltd
#
# 16th May 2011 - Orignal UCF for ML605 Board.
# 1st May 2012 - Timing constraint syntax changed to preferred style.
#
#
# Period constraint for 200MHz operation
#
NET "clk200" TNM_NET = "clk200";
TIMESPEC TS_200MHZ_clk = PERIOD "clk200" 5.0ns HIGH 50%;
#
# Period constraint for 50MHz operation
#
NET "clk" TNM_NET = "clk";
TIMESPEC TS_50MHZ_clk = PERIOD "clk" 20.0ns HIGH 50%;
#
#
# 200MHz Differential Clock.
#
NET "clk200_p" LOC = "J9" | IOSTANDARD = LVDS_25 | DIFF_TERM = TRUE;
NET "clk200_n" LOC = "H9" | IOSTANDARD = LVDS_25 | DIFF_TERM = TRUE;
#
# USB-UART
#
NET "uart_rx" LOC = "J24" | IOSTANDARD = LVCMOS25;
NET "uart_tx" LOC = "J25" | IOSTANDARD = LVCMOS25 | SLEW = SLOW | DRIVE = 4;
#
#------------------------------------------------------------------------------------------
# End of File
#------------------------------------------------------------------------------------------
#

View File

@ -0,0 +1,356 @@
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2011-2012, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and [2] Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
//
// KCPSM6 reference design using 'uart_tx6' and 'uart_rx6'macros.
//
// Ken Chapman - Xilinx Ltd.
//
// 30th April 2012 - Conversion from original VHDL version (30th April 2012).
// 30th July 2014 - Corrections to comment only.
//
// This reference design provides a simple UART communication example.
// Please see 'UART6_User_Guide_and_Reference_Designs_30Sept14.pdf' for more detailed
// descriptions.
//
// The code in this example is set to implement a 115200 baud rate when using a 50MHz
// clock. Whilst the design is presented as a working example for the XC6VLX240T-1FF1156
// device on the ML605 Evaluation Board (www.xilinx.com) it is a simple reference design
// that is easily adapted or incorporated into a design for use with any hardware platform.
//
//
//////////////////////////////////////////////////////////////////////////////////////////-
//
//
module uart6_ml605 ( input uart_rx,
input clk200_p,
input clk200_n,
output uart_tx );
//
///////////////////////////////////////////////////////////////////////////////////////////
// Signals
///////////////////////////////////////////////////////////////////////////////////////////
//
// Signals used to create 50MHz clock from 200MHz differential clock
//
wire clk200;
wire clk;
// Signals used to connect KCPSM6
wire [11:0] address;
wire [17:0] instruction;
wire bram_enable;
reg [7:0] in_port;
wire [7:0] out_port;
wire [7:0] port_id;
wire write_strobe;
wire k_write_strobe;
wire read_strobe;
wire interrupt;
wire interrupt_ack;
wire kcpsm6_sleep;
wire kcpsm6_reset;
wire rdl;
// Signals used to connect UART_TX6
wire [7:0] uart_tx_data_in;
wire write_to_uart_tx;
wire uart_tx_data_present;
wire uart_tx_half_full;
wire uart_tx_full;
reg uart_tx_reset;
// Signals used to connect UART_RX6
wire [7:0] uart_rx_data_out;
reg read_from_uart_rx;
wire uart_rx_data_present;
wire uart_rx_half_full;
wire uart_rx_full;
reg uart_rx_reset;
// Signals used to define baud rate
reg [4:0] baud_count;
reg en_16_x_baud;
//
//
///////////////////////////////////////////////////////////////////////////////////////////
//
// Start of circuit description
//
///////////////////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////////////////
// Create 50MHz clock from 200MHz differential clock
/////////////////////////////////////////////////////////////////////////////////////////
IBUFGDS diff_clk_buffer(
.I(clk200_p),
.IB(clk200_n),
.O(clk200));
// BUFR used to divide by 4 and create a regional clock
BUFR #(
.BUFR_DIVIDE("4"),
.SIM_DEVICE("VIRTEX6"))
clock_divide (
.I(clk200),
.O(clk),
.CE(1'b1),
.CLR(1'b0));
/////////////////////////////////////////////////////////////////////////////////////////
// Instantiate KCPSM6 and connect to program ROM
/////////////////////////////////////////////////////////////////////////////////////////
//
// The generics can be defined as required. In this case the 'hwbuild' value is used to
// define a version using the ASCII code for the desired letter.
//
kcpsm6 #(
.interrupt_vector (12'h7F0),
.scratch_pad_memory_size(64),
.hwbuild (8'h42)) // 42 hex is ASCII Character "B"
processor (
.address (address),
.instruction (instruction),
.bram_enable (bram_enable),
.port_id (port_id),
.write_strobe (write_strobe),
.k_write_strobe (k_write_strobe),
.out_port (out_port),
.read_strobe (read_strobe),
.in_port (in_port),
.interrupt (interrupt),
.interrupt_ack (interrupt_ack),
.reset (kcpsm6_reset),
.sleep (kcpsm6_sleep),
.clk (clk));
// Reset connected to JTAG Loader enabled Program Memory
assign kcpsm6_reset = rdl;
// Unused signals tied off until required.
assign kcpsm6_sleep = 1'b0;
assign interrupt = interrupt_ack;
// Development Program Memory
// JTAG Loader enabled for rapid code development.
uart_control #(
.C_FAMILY ("V6"),
.C_RAM_SIZE_KWORDS (2),
.C_JTAG_LOADER_ENABLE (1))
program_rom (
.rdl (rdl),
.enable (bram_enable),
.address (address),
.instruction (instruction),
.clk (clk));
/////////////////////////////////////////////////////////////////////////////////////////
// UART Transmitter with integral 16 byte FIFO buffer
/////////////////////////////////////////////////////////////////////////////////////////
//
// Write to buffer in UART Transmitter at port address 01 hex
//
uart_tx6 tx(
.data_in(uart_tx_data_in),
.en_16_x_baud(en_16_x_baud),
.serial_out(uart_tx),
.buffer_write(write_to_uart_tx),
.buffer_data_present(uart_tx_data_present),
.buffer_half_full(uart_tx_half_full ),
.buffer_full(uart_tx_full),
.buffer_reset(uart_tx_reset),
.clk(clk));
/////////////////////////////////////////////////////////////////////////////////////////
// UART Receiver with integral 16 byte FIFO buffer
/////////////////////////////////////////////////////////////////////////////////////////
//
// Read from buffer in UART Receiver at port address 01 hex.
//
// When KCPMS6 reads data from the receiver a pulse must be generated so that the
// FIFO buffer presents the next character to be read and updates the buffer flags.
//
uart_rx6 rx(
.serial_in(uart_rx),
.en_16_x_baud(en_16_x_baud ),
.data_out(uart_rx_data_out ),
.buffer_read(read_from_uart_rx ),
.buffer_data_present(uart_rx_data_present ),
.buffer_half_full(uart_rx_half_full ),
.buffer_full(uart_rx_full ),
.buffer_reset(uart_rx_reset ),
.clk(clk ));
//
/////////////////////////////////////////////////////////////////////////////////////////
// RS232 (UART) baud rate
/////////////////////////////////////////////////////////////////////////////////////////
//
// To set serial communication baud rate to 115,200 then en_16_x_baud must pulse
// High at 1,843,200Hz which is every 27.13 cycles at 50MHz. In this implementation
// a pulse is generated every 27 cycles resulting is a baud rate of 115,741 baud which
// is only 0.5% high and well within limits.
//
always @ (posedge clk )
begin
if (baud_count == 5'b11010) begin // counts 27 states including zero
baud_count <= 5'b00000;
en_16_x_baud <= 1'b1; // single cycle enable pulse
end
else begin
baud_count <= baud_count + 5'b00001;
en_16_x_baud <= 1'b0;
end
end
//
/////////////////////////////////////////////////////////////////////////////////////////
// General Purpose Input Ports.
/////////////////////////////////////////////////////////////////////////////////////////
//
// Two input ports are used with the UART macros. The first is used to monitor the flags
// on both the transmitter and receiver. The second is used to read the data from the
// receiver and generate the 'buffer_read' pulse.
//
always @ (posedge clk)
begin
case (port_id[0])
// Read UART status at port address 00 hex
1'b0 : in_port <= { 2'b00,
uart_rx_full,
uart_rx_half_full,
uart_rx_data_present,
uart_tx_full,
uart_tx_half_full,
uart_tx_data_present };
// Read UART_RX6 data at port address 01 hex
// (see 'buffer_read' pulse generation below)
1'b1 : in_port <= uart_rx_data_out;
default : in_port <= 8'bXXXXXXXX ;
endcase;
// Generate 'buffer_read' pulse following read from port address 01
if ((read_strobe == 1'b1) && (port_id[0] == 1'b1)) begin
read_from_uart_rx <= 1'b1;
end
else begin
read_from_uart_rx <= 1'b0;
end
end
//
/////////////////////////////////////////////////////////////////////////////////////////
// General Purpose Output Ports
/////////////////////////////////////////////////////////////////////////////////////////
//
// In this simple example there is only one output port and that it involves writing
// directly to the FIFO buffer within 'uart_tx6'. As such the only requirements are to
// connect the 'out_port' to the transmitter macro and generate the write pulse.
//
assign uart_tx_data_in = out_port;
assign write_to_uart_tx = write_strobe & port_id[0];
//
/////////////////////////////////////////////////////////////////////////////////////////
// Constant-Optimised Output Ports
/////////////////////////////////////////////////////////////////////////////////////////
//
// One constant-optimised output port is used to facilitate resetting of the UART macros.
//
always @ (posedge clk)
begin
if (k_write_strobe == 1'b1) begin
if (port_id[0] == 1'b1) begin
uart_tx_reset <= out_port[0];
uart_rx_reset <= out_port[1];
end
end
end
/////////////////////////////////////////////////////////////////////////////////////////
endmodule
//
///////////////////////////////////////////////////////////////////////////////////////////
// END OF FILE uart6_ml605.v
///////////////////////////////////////////////////////////////////////////////////////////
//

View File

@ -0,0 +1,481 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2011-2014, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
--
-- KCPSM6 reference design using 'uart_tx6' and 'uart_rx6'macros.
--
-- Ken Chapman - Xilinx Ltd.
--
-- 10th May 2011 - Initial version
-- 16th May 2011 - Change to comment only.
-- 20th May 2011 - Change to format only.
-- 16th June 2011 - Refined initialisation of signals.
-- 30th April 2012 - Additions and corrections to comments only.
-- 30th July 2014 - Corrections to comments only.
--
-- This reference design provides a simple UART communication example.
-- Please see 'UART6_User_Guide_and_Reference_Designs_30Sept14.pdf' for more detailed
-- descriptions.
--
-- The code in this example is set to implement a 115200 baud rate when using a 50MHz
-- clock. Whilst the design is presented as a working example for the XC6VLX240T-1FF1156
-- device on the ML605 Evaluation Board (www.xilinx.com) it is a simple reference design
-- that is easily adapted or incorporated into a design for use with any hardware platform.
--
-------------------------------------------------------------------------------------------
--
-- Library declarations
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
library unisim;
use unisim.vcomponents.all;
--
-------------------------------------------------------------------------------------------
--
--
entity uart6_ml605 is
Port ( uart_rx : in std_logic;
uart_tx : out std_logic;
clk200_p : in std_logic;
clk200_n : in std_logic);
end uart6_ml605;
--
-------------------------------------------------------------------------------------------
--
-- Start of test architecture
--
architecture Behavioral of uart6_ml605 is
--
-------------------------------------------------------------------------------------------
--
-- Components
--
-------------------------------------------------------------------------------------------
--
--
-- declaration of KCPSM6
--
component kcpsm6
generic( hwbuild : std_logic_vector(7 downto 0) := X"00";
interrupt_vector : std_logic_vector(11 downto 0) := X"3FF";
scratch_pad_memory_size : integer := 64);
port ( address : out std_logic_vector(11 downto 0);
instruction : in std_logic_vector(17 downto 0);
bram_enable : out std_logic;
in_port : in std_logic_vector(7 downto 0);
out_port : out std_logic_vector(7 downto 0);
port_id : out std_logic_vector(7 downto 0);
write_strobe : out std_logic;
k_write_strobe : out std_logic;
read_strobe : out std_logic;
interrupt : in std_logic;
interrupt_ack : out std_logic;
sleep : in std_logic;
reset : in std_logic;
clk : in std_logic);
end component;
--
-- Development Program Memory
--
component uart_control
generic( C_FAMILY : string := "S6";
C_RAM_SIZE_KWORDS : integer := 1;
C_JTAG_LOADER_ENABLE : integer := 0);
Port ( address : in std_logic_vector(11 downto 0);
instruction : out std_logic_vector(17 downto 0);
enable : in std_logic;
rdl : out std_logic;
clk : in std_logic);
end component;
--
-- UART Transmitter with integral 16 byte FIFO buffer
--
component uart_tx6
Port ( data_in : in std_logic_vector(7 downto 0);
en_16_x_baud : in std_logic;
serial_out : out std_logic;
buffer_write : in std_logic;
buffer_data_present : out std_logic;
buffer_half_full : out std_logic;
buffer_full : out std_logic;
buffer_reset : in std_logic;
clk : in std_logic);
end component;
--
-- UART Receiver with integral 16 byte FIFO buffer
--
component uart_rx6
Port ( serial_in : in std_logic;
en_16_x_baud : in std_logic;
data_out : out std_logic_vector(7 downto 0);
buffer_read : in std_logic;
buffer_data_present : out std_logic;
buffer_half_full : out std_logic;
buffer_full : out std_logic;
buffer_reset : in std_logic;
clk : in std_logic);
end component;
--
--
-------------------------------------------------------------------------------------------
--
-- Signals
--
-------------------------------------------------------------------------------------------
--
--
-- Signals used to create 50MHz clock from 200MHz differential clock
--
signal clk200 : std_logic;
signal clk : std_logic;
--
--
-- Signals used to connect KCPSM6
--
signal address : std_logic_vector(11 downto 0);
signal instruction : std_logic_vector(17 downto 0);
signal bram_enable : std_logic;
signal in_port : std_logic_vector(7 downto 0);
signal out_port : std_logic_vector(7 downto 0);
signal port_id : std_logic_vector(7 downto 0);
signal write_strobe : std_logic;
signal k_write_strobe : std_logic;
signal read_strobe : std_logic;
signal interrupt : std_logic;
signal interrupt_ack : std_logic;
signal kcpsm6_sleep : std_logic;
signal kcpsm6_reset : std_logic;
signal rdl : std_logic;
--
-- Signals used to connect UART_TX6
--
signal uart_tx_data_in : std_logic_vector(7 downto 0);
signal write_to_uart_tx : std_logic;
signal uart_tx_data_present : std_logic;
signal uart_tx_half_full : std_logic;
signal uart_tx_full : std_logic;
signal uart_tx_reset : std_logic;
--
-- Signals used to connect UART_RX6
--
signal uart_rx_data_out : std_logic_vector(7 downto 0);
signal read_from_uart_rx : std_logic;
signal uart_rx_data_present : std_logic;
signal uart_rx_half_full : std_logic;
signal uart_rx_full : std_logic;
signal uart_rx_reset : std_logic;
--
-- Signals used to define baud rate
--
signal baud_count : integer range 0 to 26 := 0;
signal en_16_x_baud : std_logic := '0';
--
--
-------------------------------------------------------------------------------------------
--
-- Start of circuit description
--
-------------------------------------------------------------------------------------------
--
begin
--
-----------------------------------------------------------------------------------------
-- Create 50MHz clock from 200MHz differential clock
-----------------------------------------------------------------------------------------
--
diff_clk_buffer: IBUFGDS
port map ( I => clk200_p,
IB => clk200_n,
O => clk200);
--
-- BUFR used to divide by 4 and create a regional clock
--
clock_divide: BUFR
generic map ( BUFR_DIVIDE => "4",
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SIM_DEVICE<EFBFBD>=> "VIRTEX6")
port map ( I => clk200,
O => clk,
CE => '1',
CLR => '0');
--
-----------------------------------------------------------------------------------------
-- Instantiate KCPSM6 and connect to program ROM
-----------------------------------------------------------------------------------------
--
-- The generics can be defined as required. In this case the 'hwbuild' value is used to
-- define a version using the ASCII code for the desired letter.
--
processor: kcpsm6
generic map ( hwbuild => X"42", -- 42 hex is ASCII Character "B"
interrupt_vector => X"7F0",
scratch_pad_memory_size => 64)
port map( address => address,
instruction => instruction,
bram_enable => bram_enable,
port_id => port_id,
write_strobe => write_strobe,
k_write_strobe => k_write_strobe,
out_port => out_port,
read_strobe => read_strobe,
in_port => in_port,
interrupt => interrupt,
interrupt_ack => interrupt_ack,
sleep => kcpsm6_sleep,
reset => kcpsm6_reset,
clk => clk);
--
-- Reset connected to JTAG Loader enabled Program Memory
--
kcpsm6_reset <= rdl;
--
-- Unused signals tied off until required.
--
kcpsm6_sleep <= '0';
interrupt <= interrupt_ack;
--
-- Development Program Memory
-- JTAG Loader enabled for rapid code development.
--
program_rom: uart_control
generic map( C_FAMILY => "V6",
C_RAM_SIZE_KWORDS => 2,
C_JTAG_LOADER_ENABLE => 1)
port map( address => address,
instruction => instruction,
enable => bram_enable,
rdl => rdl,
clk => clk);
--
-----------------------------------------------------------------------------------------
-- UART Transmitter with integral 16 byte FIFO buffer
-----------------------------------------------------------------------------------------
--
-- Write to buffer in UART Transmitter at port address 01 hex
--
tx: uart_tx6
port map ( data_in => uart_tx_data_in,
en_16_x_baud => en_16_x_baud,
serial_out => uart_tx,
buffer_write => write_to_uart_tx,
buffer_data_present => uart_tx_data_present,
buffer_half_full => uart_tx_half_full,
buffer_full => uart_tx_full,
buffer_reset => uart_tx_reset,
clk => clk);
--
-----------------------------------------------------------------------------------------
-- UART Receiver with integral 16 byte FIFO buffer
-----------------------------------------------------------------------------------------
--
-- Read from buffer in UART Receiver at port address 01 hex.
--
-- When KCPMS6 reads data from the receiver a pulse must be generated so that the
-- FIFO buffer presents the next character to be read and updates the buffer flags.
--
rx: uart_rx6
port map ( serial_in => uart_rx,
en_16_x_baud => en_16_x_baud,
data_out => uart_rx_data_out,
buffer_read => read_from_uart_rx,
buffer_data_present => uart_rx_data_present,
buffer_half_full => uart_rx_half_full,
buffer_full => uart_rx_full,
buffer_reset => uart_rx_reset,
clk => clk);
--
-----------------------------------------------------------------------------------------
-- RS232 (UART) baud rate
-----------------------------------------------------------------------------------------
--
-- To set serial communication baud rate to 115,200 then en_16_x_baud must pulse
-- High at 1,843,200Hz which is every 27.13 cycles at 50MHz. In this implementation
-- a pulse is generated every 27 cycles resulting is a baud rate of 115,741 baud which
-- is only 0.5% high and well within limits.
--
baud_rate: process(clk)
begin
if clk'event and clk = '1' then
if baud_count = 26 then -- counts 27 states including zero
baud_count <= 0;
en_16_x_baud <= '1'; -- single cycle enable pulse
else
baud_count <= baud_count + 1;
en_16_x_baud <= '0';
end if;
end if;
end process baud_rate;
--
-----------------------------------------------------------------------------------------
-- General Purpose Input Ports.
-----------------------------------------------------------------------------------------
--
-- Two input ports are used with the UART macros. The first is used to monitor the flags
-- on both the transmitter and receiver. The second is used to read the data from the
-- receiver and generate the 'buffer_read' pulse.
--
input_ports: process(clk)
begin
if clk'event and clk = '1' then
case port_id(0) is
-- Read UART status at port address 00 hex
when '0' => in_port(0) <= uart_tx_data_present;
in_port(1) <= uart_tx_half_full;
in_port(2) <= uart_tx_full;
in_port(3) <= uart_rx_data_present;
in_port(4) <= uart_rx_half_full;
in_port(5) <= uart_rx_full;
-- Read UART_RX6 data at port address 01 hex
-- (see 'buffer_read' pulse generation below)
when '1' => in_port <= uart_rx_data_out;
when others => in_port <= "XXXXXXXX";
end case;
-- Generate 'buffer_read' pulse following read from port address 01
if (read_strobe = '1') and (port_id(0) = '1') then
read_from_uart_rx <= '1';
else
read_from_uart_rx <= '0';
end if;
end if;
end process input_ports;
--
-----------------------------------------------------------------------------------------
-- General Purpose Output Ports
-----------------------------------------------------------------------------------------
--
-- In this simple example there is only one output port and that it involves writing
-- directly to the FIFO buffer within 'uart_tx6'. As such the only requirements are to
-- connect the 'out_port' to the transmitter macro and generate the write pulse.
--
uart_tx_data_in <= out_port;
write_to_uart_tx <= '1' when (write_strobe = '1') and (port_id(0) = '1')
else '0';
--
-----------------------------------------------------------------------------------------
-- Constant-Optimised Output Ports
-----------------------------------------------------------------------------------------
--
-- One constant-optimised output port is used to facilitate resetting of the UART macros.
--
constant_output_ports: process(clk)
begin
if clk'event and clk = '1' then
if k_write_strobe = '1' then
if port_id(0) = '1' then
uart_tx_reset <= out_port(0);
uart_rx_reset <= out_port(1);
end if;
end if;
end if;
end process constant_output_ports;
--
-----------------------------------------------------------------------------------------
--
end Behavioral;
-------------------------------------------------------------------------------------------
--
-- END OF FILE uart6_ml605.vhd
--
-------------------------------------------------------------------------------------------

View File

@ -0,0 +1,589 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2011-2013, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; KCPSM6 reference design using 'uart_tx6' and 'uart_rx6' macros.
;
; Ken Chapman - Xilinx Ltd
;
; 11th May 2011 - Initial version
; 6th October 2011 - Corrections to comments only
; 23rd April 2012 - UART interface routines placed into 'uart_interface_routines.psm'
; to facilitate reuse and provide an INCLUDE directive example.
; 7th September 2012 - Corrections to comments only
; 12th March 2013 - Constant directives defining ASCII control characters removed
; (pre-defined in KCPSM6 assembler v2.43 or later).
; 28th June 2013 - Corrections to comment only
;
;
; INTRODUCTION
;
; This program interacts with the 'uart_tx6' and 'uart_rx6' macros providing some simple
; and fundamental examples of UART based communication. As such, this example is intended
; to display messages on a PC based terminal (e.g. PicoTerm or HyperTerminal) and receive
; inputs typed on a keyboard by the user.
;
; The user is prompted to enter a 4-digit hexadecimal value which KCPSM6 converts to
; decimal and displays if it is valid. It is hoped that this will also provide you with
; several routines that you will find useful in your own programs.
;
; Please see 'UART6_User_Guide_30Sept12.pdf' for more detailed descriptions of the
; hardware circuit. The 'UART_TX' and 'UART_RX' routines that form the software interface
; with the macros are contained in 'uart_interface_routines.psm' together with a set of
; constants which define the allocation of I/O ports and the signals within them. The
; 'uart_interface_routines.psm' also presents an example of using the INCLUDE directive
; introduced with KCPSM6 Assembler v2.00.
;
;
;------------------------------------------------------------------------------------------
; Port definitions
;------------------------------------------------------------------------------------------
;
; The only I/O ports used in this design are those that interface with the UART macros.
; CONSTANT directives defining the port addresses and the allocation of signals within
; those ports are defined in 'uart_interface_routines.psm'.
;
;
;------------------------------------------------------------------------------------------
; Special Register usage
;------------------------------------------------------------------------------------------
;
; No registers are given special names in this program.
;
;------------------------------------------------------------------------------------------
; Scratch Pad Memory Locations
;------------------------------------------------------------------------------------------
;
CONSTANT hex_value0, 00 ;16-bit value (lower byte)
CONSTANT hex_value1, 01 ;16-bit value (upper byte)
;
CONSTANT decimal0, 02 ;5 digit decimal value
CONSTANT decimal1, 03 ; Suitable for 16-bit values up to
CONSTANT decimal2, 04 ; 65,536
CONSTANT decimal3, 05
CONSTANT decimal4, 06
;
;
;------------------------------------------------------------------------------------------
; Useful data constants
;------------------------------------------------------------------------------------------
;
;
;
;------------------------------------------------------------------------------------------
; Initialise the system
;------------------------------------------------------------------------------------------
;
; A delay of 1 second is implemented which is intended to give time for all the hardware
; to settle into a stable condition before starting to doing anything. This can be
; particularly beneficial when dealing with long cables where serial lines can take some
; time to reach the initial idle state following power being applied.
;
cold_start: CALL delay_1s ;
;
CALL reset_UART_macros ;Reset buffers in UART macros
;
;
; Initialised terminal display and display welcome messages
;
CALL clear_screen
CALL welcome_message
;
;
;------------------------------------------------------------------------------------------
; Main Program
;------------------------------------------------------------------------------------------
;
;
main: CALL send_CR
CALL send_CR
LOAD sB, prompt_msg'upper ;prompt user to enter a HEX value
LOAD sA, prompt_msg'lower
CALL send_message
CALL send_CR
CALL send_CR
LOAD s5, ">"
CALL UART_TX
CALL send_space ;advance cursor to prompt for hex value
;
LOAD sE, 4'd ;obtain 4-digit value
CALL obtain_value ;16-bit value returned in [sB,sA]
JUMP C, bad_hex_input ;Carry set for a bad hex value
STORE sA, hex_value0 ;store value in scratch pad
STORE sB, hex_value1
;
CALL send_CR
LOAD sB, result_msg'upper ;display the HEX and its decimal equivalent
LOAD sA, result_msg'lower
CALL send_message
FETCH sA, hex_value0 ;retrieve 16-bit value into [sB,sA]
FETCH sB, hex_value1
CALL send_hex_word ;send value of [sB,sA] to UART Tx
CALL send_space
LOAD s5, "i"
CALL UART_TX
LOAD s5, "s"
CALL UART_TX
CALL send_space
;
FETCH s2, hex_value0 ;retrieve 16-bit value into [s3,s2]
FETCH s3, hex_value1
CALL send_integer ;convert [s3,s2] to decimal and transmit
JUMP main
;
bad_hex_input: CALL send_CR
LOAD sB, bad_hex_msg'upper ;tell user input was invalid hex
LOAD sA, bad_hex_msg'lower
CALL send_message
JUMP main
;
;
; Text messages used in main section of the program
;
STRING prompt$, "Please enter a 4-digit hexadecimal value"
STRING bad_hex$, "Sorry, that was not a valid 4-digit hexadecimal value!"
STRING result$, "The decimal equivalent of "
;
prompt_msg: LOAD&RETURN s5, prompt$
LOAD&RETURN s5, NUL
;
bad_hex_msg: LOAD&RETURN s5, bad_hex$
LOAD&RETURN s5, NUL
;
result_msg: LOAD&RETURN s5, result$
LOAD&RETURN s5, NUL
;
;
;------------------------------------------------------------------------------------------
; Software Delays
;------------------------------------------------------------------------------------------
;
; All based on 50MHz clock
; The number of iterations of a delay loop required to form each delay required are
; loaded into the register set [s2,s1,s0] and then the delay loop is started.
;
; Registers used s0, s1, s2
;
;1ms is 50,000 clock cycles requiring 6,250 delay iterations
;
delay_1ms: LOAD s2, 00
LOAD s1, 18
LOAD s0, 6A
JUMP software_delay
;
;20ms is 1,000,000 clock cycles requiring 125,000 delay iterations
;
delay_20ms: LOAD s2, 01
LOAD s1, E8
LOAD s0, 48
JUMP software_delay
;
;1s is 50,000,000 clock cycles requiring 6,250,000 delay iterations
;
delay_1s: LOAD s2, 5F
LOAD s1, 5E
LOAD s0, 10
JUMP software_delay
;
; The delay loop decrements [s2,s1,s0] until it reaches zero
; Each decrement cycle is 4 instructions which is 8 clock cycles (160ns at 50MHz)
;
software_delay: SUB s0, 1'd
SUBCY s1, 0'd
SUBCY s2, 0'd
JUMP NZ, software_delay
RETURN
;
;
;------------------------------------------------------------------------------------------
; Clear terminal and home cursor sequences for HyperTerminal (or similar)
;------------------------------------------------------------------------------------------
;
; ANSI Escape Sequences/codes (VT100)
;
clear_screen: LOAD s5, ESC ;clear terminal sequence
CALL UART_TX
LOAD s5, "["
CALL UART_TX
LOAD s5, "2"
CALL UART_TX
LOAD s5, "J"
CALL UART_TX
CALL delay_1ms ;Delay for reliable operation
RETURN
;
cursor_home: LOAD s5, ESC ;Send cursor to upper-left of display
CALL UART_TX
LOAD s5, "["
CALL UART_TX
LOAD s5, "H"
CALL UART_TX
CALL delay_1ms ;Delay for reliable operation
RETURN
;
;
;------------------------------------------------------------------------------------------
; Welcome Message.
;------------------------------------------------------------------------------------------
;
; The welcome message includes a display of the version information available from the
; assembler and the 'hwbuild' from the instantiation of KCPSM6 in the hardware design.
;
welcome_message: LOAD sB, welcome_msg'upper
LOAD sA, welcome_msg'lower
CALL send_message
HWBUILD s5 ;hardware version defines ASCII letter
CALL UART_TX
CALL send_CR
RETURN
;
; Welcome message
;
STRING banner1$, " _ ______ ____ ____ __ __ __"
STRING banner2$, " | |/ / ___| _ \/ ___|| \/ |/ /_"
STRING banner3$, " | ' / | | |_) \___ \| |\/| | '_ \"
STRING banner4$, " | . \ |___| __/ ___) | | | | (_) )"
STRING banner5$, " |_|\_\____|_| |____/|_| |_|\___/"
;
; Welcome message
;
STRING welcome1$, "Example using the 'uart_tx6' and 'uart_rx6' macros"
STRING welcome2$, "Assembly Date: "
STRING welcome3$, " Time: "
STRING welcome4$, "Assembler Version: "
STRING welcome5$, "Hardware Design: "
;
;
welcome_msg: LOAD&RETURN s5, banner1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner2$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner3$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner4$
LOAD&RETURN s5, CR
LOAD&RETURN s5, banner5$
LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome1$
LOAD&RETURN s5, CR
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome2$
LOAD&RETURN s5, datestamp$
LOAD&RETURN s5, welcome3$
LOAD&RETURN s5, timestamp$
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome4$
LOAD&RETURN s5, KCPSM6_version$
LOAD&RETURN s5, CR
LOAD&RETURN s5, welcome5$
LOAD&RETURN s5, NUL
;
;
;------------------------------------------------------------------------------------------
; Send a message to the UART
;------------------------------------------------------------------------------------------
;
; A message is transmitted to the USB-UART.
; The start address of the message must be provided in [sB,sA].
; Terminate the transmission with a NULL character (00 hex).
;
send_message: CALL@ (sB, sA)
COMPARE s5, 00 ;terminate on NUL character
RETURN Z
CALL UART_TX
ADD sA, 1'd
ADDCY sB, 0'd
JUMP send_message
;
;
;------------------------------------------------------------------------------------------
; Send Carriage Return to UART
;------------------------------------------------------------------------------------------
;
; Registers used s0, s1, s2, and s5.
;
send_CR: LOAD s5, CR
JUMP UART_TX ;includes RETURN
;
;
;------------------------------------------------------------------------------------------
; Send a Space to UART
;------------------------------------------------------------------------------------------
;
; Registers used s0, s1, s2, and s5.
;
send_space: LOAD s5, " "
JUMP UART_TX ;includes RETURN
;
;
;------------------------------------------------------------------------------------------
; Send Hex Value of 16-bit word to UART
;------------------------------------------------------------------------------------------
;
; Value provided in register pair [sB,sA] is sent as ASCII HEX to the UART
; transmitter.
;
; Registers used s0, s1, s2, s4, s5, sA and sB.
;
send_hex_word: LOAD s4, sB
CALL send_hex_byte
LOAD s4, sA
JUMP send_hex_byte ;includes RETURN
;
;
;------------------------------------------------------------------------------------------
; Send Hex Value of Byte to UART
;------------------------------------------------------------------------------------------
;
; Value provided in register 's4' is sent as ASCII HEX to the UART transmitter.
;
; Registers used s0, s4 (preserved) and s5.
;
send_hex_byte: LOAD s5, s4 ;isolate upper nibble
SR0 s5
SR0 s5
SR0 s5
SR0 s5
CALL hex_to_ASCII ; convert to ASCII
CALL UART_TX ;send upper digit to UART
LOAD s5, s4 ;isolate lower nibble
AND s5, 0F
CALL hex_to_ASCII ; convert to ASCII
CALL UART_TX ;send lower digit to UART
RETURN
;
; Convert value 00 to 0F provided in 's5' into ASCII character in 's5'
;
; Register used s5
;
hex_to_ASCII: SUB s5, 0A ;test if value is in range 0 to 9
JUMP C, number_char
ADD s5, 07 ;ASCII char A to F in range 41 to 46
number_char: ADD s5, 3A ;ASCII char 0 to 9 in range 30 to 40
RETURN
;
;
;------------------------------------------------------------------------------------------
; Converts character to upper case
;------------------------------------------------------------------------------------------
;
; Tests and converts character in 's5' (if necessary).
;
; To convert character to upper case
;
; If the character is in the range 'a' to 'z', it is converted
; to the equivalent upper case character in the range 'A' to 'Z'.
; All other characters remain unchanged.
;
upper_case: COMPARE s5, "a" ;eliminate character codes below 'a' (61 hex)
RETURN C
COMPARE s5, 7B ;eliminate character codes above 'z' (7A hex)
RETURN NC
AND s5, 11011111'b ;force bit5 Low to convert to upper case
RETURN
;
;
;------------------------------------------------------------------------------------------
; Convert ASCII character to an equivalent HEX value.
;------------------------------------------------------------------------------------------
;
; Converts the ASCII character presented in 's5' to an equivalent HEX value.
; If character is not valid for hex, then CARRY is set on return.
;
; Register used s5
;
ASCII_to_hex: ADD s5, B9 ;test for above ASCII code 46 ('F')
RETURN C
SUB s5, E9 ;normalise 0 to 9 with A-F in 11 to 16 hex
RETURN C ;reject below ASCII code 30 ('0')
SUB s5, 11 ;isolate A-F down to 00 to 05 hex
JUMP NC, ASCII_letter
ADD s5, 07 ;test for above ASCII code 46 ('F')
RETURN C
SUB s5, F6 ;convert to range 00 to 09
RETURN
ASCII_letter: ADD s5, 0A ;convert to range 0A to 0F
RETURN
;
;
;------------------------------------------------------------------------------------------
; Read ASCII-HEX value up to 8-digits (for 32-bit value) from UART
;------------------------------------------------------------------------------------------
;
; Read up to 8 hex characters from UART and convert to a binary value in the [sD,sC,sB,sA]
; register set. The number of characters to be read must be defined in sE. When less than
; 8 characters are read the value is returned in the least significant bits of the register
; set with the 8-bits above the defined value being zero to ensure ensuring that the upper
; nibble will be zero if an odd number of digits are read.
;
; If any character received from the UART is not in the range 0 to F then the routine will
; end immediately with the CARRY flag set and this should be checked by the calling process
; upon return.
;
obtain_value: LOAD sA, 00 ;initialise potentially unused bits to zero
obtain_digit: CALL UART_RX ;wait for a character and return in s5
JUMP Z, obtain_digit ;continue to wait if timeout occurs
CALL UART_TX ;echo character as entered
CALL upper_case ;convert to upper case if necessary
CALL ASCII_to_hex ;convert value in s5 to hex nibble
RETURN C ;If invalid hex digit then return immediately
LOAD s0, 4'd ;shift [sD,sC,sB,sA] left by 4 bits
build_value: SL0 sA ; to make space for new digit value
SLA sB
SLA sC
SLA sD
SUB s0, 1'd
JUMP NZ, build_value
OR sA, s5 ;merge value of new digit into existing value
SUB sE, 01 ;count number of digits obtained
JUMP NZ, obtain_digit
RETURN
;
;
;------------------------------------------------------------------------------------------
; Send integer in decimal format to UART Tx
;------------------------------------------------------------------------------------------
;
; The 16-bit value provided in [s3,s2] should be a positive integer and will be displayed
; using 1 to 5 digits for values up to 65535 (i.e. leading zeros are blanked).
;
;
send_integer: COMPARE s2, 00 ;test for special case of zero
COMPARECY s3, 00
JUMP Z, zero_integer
;
CALL integer16_to_BCD ;Convert to BCD in SPM
;
LOAD sA, decimal4 ;pointer to BCD in SPM
LOAD sB, 0'd ;flag for leading zero blanking
send_integer_loop: FETCH s5, (sA)
ADD sB, s5 ;make sB non-zero to stop blanking
COMPARE sB, 0'd ;Test for blanking
JUMP Z, next_int_digit
ADD s5, "0" ;convert to ASCII
CALL UART_TX ;send digit
next_int_digit: COMPARE sA, decimal0
RETURN Z
SUB sA, 1'd ;move pointer to next digit
JUMP send_integer_loop
;
zero_integer: LOAD s5, "0" ;special response for zero
CALL UART_TX
RETURN
;
;
;------------------------------------------------------------------------------------------
; 16-bit integer to BCD conversion
;------------------------------------------------------------------------------------------
;
; Convert the 16 bit value up to FFFF hex in register set [s3,s2]
; into the BCD decimal equivalent up to 65,535 located in the scratch pad memory
; locations 'decimal0' to 'decimal4' which must be in ascending locations.
;
; Each digit is formed in turn starting with the least significant. The value
; contained in [s3,s2] is divided by 10 and the remainder of that integer division
; is the value of each digit in the range 0 to 9.
;
; Registers used s0,s2,s3,s4,s8,s9,sA,sB
;
integer16_to_BCD: LOAD s4, decimal0 ;pointer for LS-Digit in scratch pad memory
int_to_BCD_loop: CALL divide_16bit_by_10
STORE sA, (s4) ;remainder is the digit value
COMPARE s4, decimal4 ;test for MS-Digit completed
RETURN Z
ADD s4, 1'd ;advance pointer to next digit
JUMP int_to_BCD_loop
;
; Divide 16-bit binary integer by 10
;
; The value to be divided by 10 should be provided in register set [s3,s2].
; The routine will return the integer result [s3,s2]/10 back in[s3,s2]
; with any remainder in (0 to 9) in register sA.
;
; Registers used s0,s2,s3,s8,s9,sA,sB
;
divide_16bit_by_10: LOAD sA, s2 ;copy input value into [sB,sA]
LOAD sB, s3
LOAD s2, 00 ;clear division result
LOAD s3, 00
LOAD s9, A0 ;initialise [s9,s8] with '10' in MSBs
LOAD s8, 00
LOAD s0, 13'd ;13 subtract and shift iterations to be performed
div10_loop: SUB sA, s8 ;perform 16-bit subtract [sB,sA]-[s9,s8]
SUBCY sB, s9
JUMP C, div10_restore ;if carry then could not subtract from total
SL1 s2 ;shift '1' into result because subtract ok
JUMP div10_shifts
div10_restore: ADD sA, s8 ;perform 16-bit addition [sB,sA]+[s9,s8]
ADDCY sB, s9 ;to restore total
SL0 s2 ;shift '0' into result because could no subtract
div10_shifts: SLA s3 ;complete 16-bit shift left into [s3,s2]
SR0 s9 ;divide '10' value by 2 (shift right 1 place)
SRA s8
SUB s0, 01 ;count iterations
RETURN Z ;on return the remainder of division is in sA
JUMP div10_loop
;
;
;------------------------------------------------------------------------------------------
; Include PSM files
;------------------------------------------------------------------------------------------
;
; The INCLUDE directive enables commonly routines to be kept in their own PSM files and
; easily reused in different programs (i.e. avoiding 'cut and paste'). It also allows
; each PSM to remain a more manageable size.
;
;
; Include routines that implement interface with UART macros.
; -----------------------------------------------------------
;
INCLUDE "uart_interface_routines.psm"
;
;
;------------------------------------------------------------------------------------------
; End of Program
;------------------------------------------------------------------------------------------
;

View File

@ -0,0 +1,188 @@
;
;------------------------------------------------------------------------------------------
; Copyright <20> 2011-2012, Xilinx, Inc.
; This file contains confidential and proprietary information of Xilinx, Inc. and is
; protected under U.S. and international copyright and other intellectual property laws.
;------------------------------------------------------------------------------------------
;
; Disclaimer:
; This disclaimer is not a license and does not grant any rights to the materials
; distributed herewith. Except as otherwise provided in a valid license issued to
; you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
; MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
; DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
; INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
; OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
; (whether in contract or tort, including negligence, or under any other theory
; of liability) for any loss or damage of any kind or nature related to, arising
; under or in connection with these materials, including for any direct, or any
; indirect, special, incidental, or consequential loss or damage (including loss
; of data, profits, goodwill, or any type of loss or damage suffered as a result
; of any action brought by a third party) even if such damage or loss was
; reasonably foreseeable or Xilinx had been advised of the possibility of the same.
;
; CRITICAL APPLICATIONS
; Xilinx products are not designed or intended to be fail-safe, or for use in any
; application requiring fail-safe performance, such as life-support or safety
; devices or systems, Class III medical devices, nuclear facilities, applications
; related to the deployment of airbags, or any other applications that could lead
; to death, personal injury, or severe property or environmental damage
; (individually and collectively, "Critical Applications"). Customer assumes the
; sole risk and liability of any use of Xilinx products in Critical Applications,
; subject only to applicable laws and regulations governing limitations on product
; liability.
;
; THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
;
;------------------------------------------------------------------------------------------
;
; _ ______ ____ ____ __ __ __
; | |/ / ___| _ \/ ___|| \/ |/ /_
; | ' / | | |_) \___ \| |\/| | '_ \
; | . \ |___| __/ ___) | | | | (_) )
; |_|\_\____|_| |____/|_| |_|\___/
;
;
; PicoBlaze Reference Design.
;
;
; Ken Chapman - Xilinx Ltd
;
; 23rd April 2012 - Initial Release
; 24th July 2012 - Corrections to comments only
;
; This file contains routines used to interface with the UART6 macros provided with KCPSM6
; and was first supplied with a reference design called 'uart6_605' included in the
; PicoBlaze package. The routines enable characters to be transmitted to and received
; from the UART macros as well as perform a reset of the FIFO the buffers.
;
; NOTE - This is not a standalone PSM file. The 'uart_control.psm' file supplied with
; the reference design stated above includes this file and calls the routines
; contained in this file.
;
; INCLUDE "uart_interface_routines.psm"
;
; Hint - The INCLUDE directive was introduced in KCPSM6 Assembler v2.00.
;
;
; Whilst the reference design stated above was presented for the UART macros connected to
; the USB/UART interface on the Xilinx ML605 Evaluation Kit this file can be ported to
; any design for any board simply by setting the appropriate values in the CONSTANT
; directives described below.
;
;
;------------------------------------------------------------------------------------------
; Hardware Constants
;------------------------------------------------------------------------------------------
;
; The CONSTANT directives below define the input and output ports assigned to the UART
; macros that implement a 115,200 baud rate communication with the USB/UART on the board.
; Additional constants identify the allocation of signals to bits within a port.
;
;
;
; UART Status
; -----------
;
CONSTANT UART_status_port, 00 ; Read status
CONSTANT UART_Tx_data_present, 00000001'b ; Tx data_present - bit0
CONSTANT UART_Tx_half_full, 00000010'b ; half_full - bit1
CONSTANT UART_Tx_full, 00000100'b ; full - bit2
CONSTANT UART_Rx_data_present, 00001000'b ; Rx data_present - bit3
CONSTANT UART_Rx_half_full, 00010000'b ; half_full - bit4
CONSTANT UART_Rx_full, 00100000'b ; full - bit5
;
; Write data to UART_TX6
; ----------------------
;
CONSTANT UART_TX6_output_port, 01
;
; Read data from UART_RX6
; -----------------------
;
CONSTANT UART_RX6_input_port, 01
;
; Reset UART buffers (Constant Optimised Port)
; --------------------------------------------
;
CONSTANT reset_UART_port, 01
CONSTANT UART_tx_reset, 00000001'b ; uart_tx6 reset - bit0
CONSTANT UART_rx_reset, 00000010'b ; uart_rx6 reset - bit1
CONSTANT UART_reset, 00000011'b ; reset Tx and Rx
CONSTANT UART_operate, 00000000'b ; Tx and Rx free to operate
;
;
;--------------------------------------------------------------------------------------
; Routine to reset UART Buffers inside 'uart_tx6' and 'uart_rx6'
;--------------------------------------------------------------------------------------
;
; This routine will generate and apply an active High reset pulse to the FIFO
; buffers in both the transmitter and receiver macros.
;
; Note that the reset signals have been assigned to a constant optimised output port
; so the 'OUTPUTK' instructions are used and no registers contents are affected.
;
;
reset_UART_macros: OUTPUTK UART_reset, reset_UART_port
OUTPUTK UART_operate, reset_UART_port
RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to send one character to the UART Transmitter 'uart_tx6'
;--------------------------------------------------------------------------------------
;
; This routine will transmit the character provided in register 's5'.
;
; Before the character is output to the 'UART_TX6' macro the status of the FIFO buffer
; is checked to see if there is space. If the buffer is full then this routine will
; wait for space to become available (e.g. the time required for a previous character
; to be transmitted by the UART).
;
; Registers used s0 and s5 for the data (which is preserved)
;
UART_TX: INPUT s0, UART_status_port ;Check if buffer is full
TEST s0, UART_Tx_full
JUMP NZ, UART_TX ;wait if full
OUTPUT s5, UART_TX6_output_port
RETURN
;
;
;--------------------------------------------------------------------------------------
; Routine to attempt to receive one character from the UART Receiver 'uart_rx6'
;--------------------------------------------------------------------------------------
;
; This routine will attempt to receive one character from the 'UART_RX6' macro, and if
; successful, will return that character in register 's5' and the Zero flag will be
; reset (Z=0).
;
; If there are no characters available to be read from the FIFO buffer within the
; 'UART_RX6' macro then this routine will timeout after ~2,000 clock cycles (which is
; 40us at 50MHz) with the Zero flag set (Z=1). This timeout scheme ensures that KCPSM6
; cannot become stuck in this routine if no characters are received. If you do want
; KCPSM6 to wait indefinitely for a character to be received then either modify this
; routine or perform a test of the Zero flag and repeat the call to this routine as
; shown in this example...
;
; wait_for_UART_RX: CALL UART_RX
; JUMP Z, wait_for_UART_RX
;
;
; Registers used s0, s1 and s5.
;
UART_RX: LOAD s1, 167'd ;Timeout = 167 x (6 instructions x 2 clock cycles)
rx_timeout: INPUT s0, UART_status_port
TEST s0, UART_Rx_data_present ;Z=0 and C=1 when data present
JUMP NZ, read_Rx
SUB s1, 1'd
RETURN Z ;Timeout returns with Z=1 and C=0
JUMP rx_timeout
;
read_Rx: INPUT s5, UART_RX6_input_port ;read character from buffer
RETURN
;
;
;------------------------------------------------------------------------------------------
; End of 'uart_interface_routines.psm"'
;------------------------------------------------------------------------------------------
;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,383 @@
<EFBFBD> Copyright 2010-2014, Xilinx, Inc. All rights reserved.
This file contains confidential and proprietary information of Xilinx, Inc. and is
protected under U.S. and international copyright and other intellectual property laws.
Disclaimer:
This disclaimer is not a license and does not grant any rights to the materials
distributed herewith. Except as otherwise provided in a valid license issued to you
by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE MATERIALS
ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL
WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED
TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR
PURPOSE; and (2) Xilinx shall not be liable (whether in contract or tort, including
negligence, or under any other theory of liability) for any loss or damage of any
kind or nature related to, arising under or in connection with these materials,
including for any direct, or any indirect, special, incidental, or consequential
loss or damage (including loss of data, profits, goodwill, or any type of loss or
damage suffered as a result of any action brought by a third party) even if such
damage or loss was reasonably foreseeable or Xilinx had been advised of the
possibility of the same.
CRITICAL APPLICATIONS
Xilinx products are not designed or intended to be fail-safe, or for use in any
application requiring fail-safe performance, such as life-support or safety devices
or systems, Class III medical devices, nuclear facilities, applications related to
the deployment of airbags, or any other applications that could lead to death,
personal injury, or severe property or environmental damage (individually and
collectively, "Critical Applications"). Customer assumes the sole risk and
liability of any use of Xilinx products in Critical Applications, subject only to
applicable laws and regulations governing limitations on product liability.
THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
-------------------------------------------------------------------------------------------------
UART Macros for Spartan-6, Virtex-6, 7-Series, Zynq and UltraScale Devices
-------------------------------------------------------------------------------------------------
Release 5.
Ken Chapman - Xilinx Ltd - 30th September 2014
Welcome to the fifth release of the UART macros optimised for Spartan-6, Virtex-6,7-Series, Zynq
and UltraScale devices and ideally suited for use with PicoBlaze (KCPSM6).
There have been no changes to the actual UART macros since the first release. Minor corrections
have been made to the documentation (thank you to those that reported issues).
The most significant reason for this release has been the addition of a third reference design.
This new reference is presented on the KC705 board but the main feature is a scheme in which
PicoBlaze (KCPSM6) adjusts the communication BAUD rate and software delays to reflect the clock
frequency. Please see 'UART6_User_Guide_and_Reference_Designs_30Sept14' for descriptions of
all three reference designs provided. This design has been implemented using both ISE and Vivado
and therefore both UCF and XDC constraints files have been provided.
Hint - The KCPSM6 package includes more reference designs that use the UART
macros on a Kintex-7 KC705 board.
PicoTerm (v1.97) may now be invoked with a command line option that will open and write a log
file. 'PicoTerm_README.txt' documents all the features of PicoTerm and the reference design
presented on the ATLYS board demonstrates many of the possibilities.
Xilinx Technical Support is available to answer your questions. However it is recommended that
you take the time to consider exactly what your issue is before asking any questions. Just
because your design contains the UART macros (and probably a PicoBlaze processor) it doesn't
mean you actually have a problem with either! Page 13 of the 'UART6_User_Guide' recommends
steps to debug a UART communication link and every item on this list should be checked before
contacting Xilinx Technical Support.
http://www.xilinx.com/support/clearexpress/websupport.htm
-------------------------------------------------------------------------------------------------
Principle Features of 'uart_tx6' and 'uart_rx6' macros.
-------------------------------------------------------------------------------------------------
- 8-bit data, 1 stop bit, no parity.
- User definable baud rate.
- Integrated 16-byte FIFO buffers.
- Performance of >10mbps (baud rate) achievable depending on device family and clock rate.
- No handshake but signals provided facilitate implementation of soft or hardware schemes.
- Each macro is only 5 Slices including the FIFO buffer.
- Ideal peripherals for PicoBlaze (KCPSM6).
-------------------------------------------------------------------------------------------------
'UART' Directory Contents
-------------------------------------------------------------------------------------------------
UART6_README.txt - This file!
UART6_User_Guide_and_Reference_Designs_29March13.pdf - The main UART6 User Guide document.
uart_tx6.vhd - UART transmitter with integrated 16-byte FIFO buffer.
uart_rx6.vhd - UART receiver with integrated 16-byte FIFO buffer.
uart_tx6.v - Verilog equivalent of 'uart_tx6.vhd'.
uart_rx6.v - Verilog equivalent of 'uart_rx6.vhd'.
PicoTerm.exe - A very simple PC based terminal but with some special features!
PicoTerm_README.txt - Description of PicoTerm basic usage and special features.
'ML605_design' Directory
------------------------
uart6_ml605.vhd - KCPSM6 reference design using 'uart_tx6' and 'uart_rx6'.
Can be used as provided with the ML605 evaluation board.
uart6_ml605.v - Verilog equivalent of 'uart6_ml605.vhd'.
uart_control.psm - Top level KCPSM6 program for 'uart6_ml605' design.
INCLUDE directive used to include 'uart_interface_routines.psm'.
uart_interface_routines.psm - UART interface definition and UART routines.
uart6_ml605.ucf - ISE constraints file when using an ML605 board.
'ATLYS_design' Directory
------------------------
uart6_atlys.vhd - KCPSM6 reference design using 'uart_tx6' and 'uart_rx6'.
Design is described in the PDF document.
Can be used as provided with the ATLYS Design Platform.
uart6_atlys.v - Verilog equivalent of 'uart6_atlys.vhd'.
atlys_real_time_clock.psm - Top level KCPSM6 program for 'uart6_atlys.vhd' design.
INCLUDE directives used to include 'PicoTerm_routines.psm'
and 'soft_delays_100mhz.psm'.
PicoTerm_routines.psm - UART interface definition and UART routines including routines
written specifically to use PicoTerm's special features.
soft_delays_100mhz.psm - Routines implementing delays based on a 100MHz clock.
uart6_atlys.ucf - ISE constraints file when using an ATLYS Design Platform.
'KC705_design' Directory
------------------------
uart6_kc705.vhd - KCPSM6 reference design using 'uart_tx6' and 'uart_rx6'.
Can be used as provided with the KC705 evaluation board.
uart6_kc705.v - Verilog equivalent of 'uart6_kc705.vhd'.
auto_baud_rate_control.psm - Top level KCPSM6 program for 'uart6_kc705' design.
INCLUDE directive used to include 'uart_interface_routines.psm'.
uart_interface_routines.psm - UART interface definition and UART routines.
uart6_kc705.ucf - ISE constraints file when using a KC705 board.
uart6_kc705.xdc - Vivado constraints file when using a KC705 board.
testbench_uart6_kc705.vhd - Simple test bench. The waveforms shown on page 22 of
'UART6_User_Guide_and_Reference_Designs_30Sept14.pdf'
were captured from the Vivado simulator using this test bench.
-------------------------------------------------------------------------------------------------
Requirements
-------------------------------------------------------------------------------------------------
ISE v12.x or later (v14.7 current at time of this release)
or
Vivado 2013.x or later (2014.2 current at time of this release)
These UART macros are optimised for Spartan-6, Virtex-6 and 7-Series devices. They also map well
to UltraScale devices but they can NOT be used with previous generations of device including
Spartan-3 Generation and Virtex-5.
The KCPSM6 Assembler v2.70 was current at the time this package. Older versions of the KCPSM6
Assembler may not recognise all the syntax present in the PSM files provided with the reference
designs in this release.
-------------------------------------------------------------------------------------------------
Changes and Additions
-------------------------------------------------------------------------------------------------
Release 1
---------
Initial release
Release 2
---------
Enhancements to documentation.
PicoTerm v1.03 - Basic terminal features only.
Release 3
---------
ATLYS reference design and documentation.
PicoTerm v1.30 - With Device Control String (DCS) features.
Release 4
---------
Enhancements to the ATLYS reference design.
PicoTerm v1.72 - With more Device Control String (DCS) features.
Release 5
---------
KC705 reference design and documentation.
PicoTerm v1.97 - Additional command line option to open a log file.
-------------------------------------------------------------------------------------------------
Known Issues
-------------------------------------------------------------------------------------------------
Terminal only displays everything on one line
---------------------------------------------
As shown in the reference programs (PSM files) provided, it is common practice for each line of
text to end with a carriage return character (0D hex) only. Your terminal should be configured to
append a line feed automatically to a carriage return. In HyperTerminal this is the 'Append line
feeds to incoming line ends' option in the ASCII Setup menu.
PicoTerm is permanently set to meet this end of line requirement. It is also permanently set to
match the 8-bit, 1 stop bit and no parity configuration required to work with the UART6 macros
as well as having a default baud rate of 115200. All of this should make PicoTerm easy to use
and a good alternative if you are experiencing issue with another terminal. At least give it a
try!
Incorrect removal of logic during implementation
------------------------------------------------
Setting 'global_opt' option in MAP to 'speed', 'area' or 'power' may result in the incorrect
removal of the serial input to the receiver which leads on to the removal of the whole macro!
A good implementation is realised when 'global_opt' is set to 'off' (the default setting).
This issue was observed when using ISE v12.4 and may also apply to some other versions of ISE.
This issue was fixed in ISE v13.4 so you must use ISE v13.4 when 'global_opt' needs to be used
for other parts of your design.
Note that 'global_opt' is only applicable to Spartan-6 and Virtex-6 designs so this should
never be an issue for 7-Series designs.
The first few characters are corrupted but then everything works as expected
----------------------------------------------------------------------------
This can occur when the UART macros are used to transmit characters to a PC almost immediately
after the device is configured. The simple solution is to implement a delay (e.g. ~1 second)
before the first transmission is attempted. This is very easy to arrange when using PicoBlaze
(see reference code provided).
Should this issue occur it is almost certainly the case that the UART communications involve a
USB/UART converter device with a corresponding Virtual COM Port driver on the PC. Whilst the UART
transmitter macro transmits characters correctly, it is not entirely fair to blame the USB/UART
arrangement because the serial communication is ultimately recovering from what is known as a
'break condition'. In other words, until the FPGA was configured, there was nothing to define
the state of the serial line. In theory, a serial line should be parked High when not active
but in this case it has probably been Low which would be consistent with a broken or disconnected
link. Depending on the vendor of the device and driver, it appears that some take more time to
recover from the break condition. Again to be fair, the serial line really needs to be High
long enough for the first start bit Low to be recognised correctly and typical baud rates are
slow relative to the typical clock speeds used in FPGA designs.
-------------------------------------------------------------------------------------------------
Hints and Tips
-------------------------------------------------------------------------------------------------
Simulation
----------
As covered in the main documentation, a UART can appear very slow relative to the clock so if
you want to see an output from UART_TX6 or simulate an input to UART_RX6 then just remember that
your simulation may be rather long or you really need to zoom out to see the waveforms.
When performing a functional simulation it is your responsibility to ensure that all your
stimuli have defined values at time zero to represent what would happen in the real silicon.
In particular the circuit you use to generate the 'en_16_x_baud' pulses should be such that this
signal also has a defined value before the first rising edge is applied to the clock input of
UART_TX6. The easiest way to do this is to make sure that initial values are defined. E.g....
signal en_16_x_baud : std_logic := '0';
-------------------------------------------------------------------------------------------------
UART pin assignments for commonly used boards
-------------------------------------------------------------------------------------------------
Drigmorn3 (www.enterpoint.co.uk)
--------------------------------
NET "uart_rx" LOC = "G11" | IOSTANDARD = LVTTL;
NET "uart_tx" LOC = "A11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 4;
LX9 Microboard: AES-S6MB-LX9-G (www.em.avnet.com/drc)
-----------------------------------------------------
NET "rs232_rx" LOC = "R7" | IOSTANDARD = LVCMOS33;
NET "rs232_tx" LOC = "T7" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4;
LX16 Evaluation board: AES-S6EV-LX16-G (www.em.avnet.com/drc)
-------------------------------------------------------------
NET "rs232_rx" LOC = "H13" | IOSTANDARD = LVCMOS33;
NET "rs232_tx" LOC = "H14" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4;
ATLYS (www.digilentinc.com)
----------------------------
NET "rs232_rx" LOC = "A16" | IOSTANDARD = LVCMOS33;
NET "rs232_tx" LOC = "B16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4;
SP601
-----
NET "uart_rx" LOC = "K14" | IOSTANDARD = LVCMOS25;
NET "uart_tx" LOC = "L12" | IOSTANDARD = LVCMOS25 | SLEW = SLOW | DRIVE = 4;
SP605 (www.xilinx.com)
-----------------------
NET "uart_rx" LOC = "H17" | IOSTANDARD = LVCMOS25;
NET "uart_tx" LOC = "B21" | IOSTANDARD = LVCMOS25 | SLEW = SLOW | DRIVE = 4;
ML605 (www.xilinx.com)
----------------------
NET "uart_rx" LOC = "J24" | IOSTANDARD = LVCMOS25;
NET "uart_tx" LOC = "J25" | IOSTANDARD = LVCMOS25 | SLEW = SLOW | DRIVE = 4;
KC705 (www.xilinx.com)
----------------------
(Correct for Rev.D board but check pin assignments if using an earlier revision)
NET "uart_rx" LOC = "M19" | IOSTANDARD = LVCMOS25;
NET "uart_tx" LOC = "K24" | IOSTANDARD = LVCMOS25 | SLEW = SLOW | DRIVE = 4;
VC707 (www.xilinx.com)
----------------------
NET "uart_rx" LOC = "AU33" | IOSTANDARD = LVCMOS18;
NET "uart_tx" LOC = "AU36" | IOSTANDARD = LVCMOS18 | SLEW = SLOW | DRIVE = 4;
-------------------------------------------------------------------------------------------------
End of file 'UART6_README.txt'
-------------------------------------------------------------------------------------------------

View File

@ -0,0 +1,514 @@
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2011, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
// UART Receiver with integral 16 byte FIFO buffer
//
// 8 bit, no parity, 1 stop bit
//
// This module was made for use with Spartan-6 Generation Devices and is also ideally
// suited for use with Virtex-6 and 7-Series devices.
//
// Version 1 - 8th July 2011.
// Derived from uart_rx6.vhd Version 1 (31st March 2011) by Nick Sawyer.
//
// Ken Chapman
// Xilinx Ltd
// Benchmark House
// 203 Brooklands Road
// Weybridge
// Surrey KT13 ORH
// United Kingdom
//
// chapman@xilinx.com
//
///////////////////////////////////////////////////////////////////////////////////////////
//
// Format of this file.
//
// The module defines the implementation of the logic using Xilinx primitives.
// These ensure predictable synthesis results and maximise the density of the
// implementation. The Unisim Library is used to define Xilinx primitives. It is also
// used during simulation.
// The source can be viewed at %XILINX%\verilog\src\unisims\
//
///////////////////////////////////////////////////////////////////////////////////////////
//
`timescale 1 ps / 1ps
module uart_rx6 (
input serial_in,
input en_16_x_baud,
output [7:0] data_out,
input buffer_read,
output buffer_data_present,
output buffer_half_full,
output buffer_full,
input buffer_reset,
input clk );
//
///////////////////////////////////////////////////////////////////////////////////////////
//
// wires used in uart_rx6
//
///////////////////////////////////////////////////////////////////////////////////////////
//
wire [3:0] pointer_value;
wire [3:0] pointer;
wire en_pointer;
wire zero;
wire full_int;
wire data_present_value;
wire data_present_int;
wire sample_value;
wire sample;
wire sample_dly_value;
wire sample_dly;
wire stop_bit_value;
wire stop_bit;
wire [7:0] data_value;
wire [7:0] data;
wire run_value;
wire run;
wire start_bit_value;
wire start_bit;
wire [3:0] div_value;
wire [3:0] div;
wire div_carry;
wire sample_input_value;
wire sample_input;
wire buffer_write_value;
wire buffer_write;
//
///////////////////////////////////////////////////////////////////////////////////////////
//
// Start of uart_rx6 circuit description
//
///////////////////////////////////////////////////////////////////////////////////////////
//
genvar i;
// SRL16E data storage
generate
for (i = 0 ; i <= 7 ; i = i+1)
begin : data_width_loop
(* HBLKNM = "uart_rx6_5" *)
SRL16E #(
.INIT (16'h0000))
storage_srl (
.D (data[i]),
.CE (buffer_write),
.CLK (clk),
.A0 (pointer[0]),
.A1 (pointer[1]),
.A2 (pointer[2]),
.A3 (pointer[3]),
.Q (data_out[i]));
end //generate data_width_loop;
endgenerate
(* HBLKNM = "uart_rx6_1" *)
LUT6 #(
.INIT (64'hFF00FE00FF80FF00))
pointer3_lut(
.I0 (pointer[0]),
.I1 (pointer[1]),
.I2 (pointer[2]),
.I3 (pointer[3]),
.I4 (buffer_write),
.I5 (buffer_read),
.O (pointer_value[3]));
(* HBLKNM = "uart_rx6_1" *)
FDR pointer3_flop(
.D (pointer_value[3]),
.Q (pointer[3]),
.R (buffer_reset),
.C (clk));
(* HBLKNM = "uart_rx6_1" *)
LUT6 #(
.INIT (64'hF0F0E1E0F878F0F0))
pointer2_lut(
.I0 (pointer[0]),
.I1 (pointer[1]),
.I2 (pointer[2]),
.I3 (pointer[3]),
.I4 (buffer_write),
.I5 (buffer_read),
.O (pointer_value[2]));
(* HBLKNM = "uart_rx6_1" *)
FDR pointer2_flop(
.D (pointer_value[2]),
.Q (pointer[2]),
.R (buffer_reset),
.C (clk));
(* HBLKNM = "uart_rx6_1" *)
LUT6_2 #(
.INIT (64'hCC9060CCAA5050AA))
pointer01_lut(
.I0 (pointer[0]),
.I1 (pointer[1]),
.I2 (en_pointer),
.I3 (buffer_write),
.I4 (buffer_read),
.I5 (1'b1),
.O5 (pointer_value[0]),
.O6 (pointer_value[1]));
(* HBLKNM = "uart_rx6_1" *)
FDR pointer1_flop(
.D (pointer_value[1]),
.Q (pointer[1]),
.R (buffer_reset),
.C (clk));
(* HBLKNM = "uart_rx6_1" *)
FDR pointer0_flop(
.D (pointer_value[0]),
.Q (pointer[0]),
.R (buffer_reset),
.C (clk));
(* HBLKNM = "uart_rx6_1" *)
LUT6_2 #(
.INIT (64'hF4FCF4FC040004C0))
data_present_lut(
.I0 (zero),
.I1 (data_present_int),
.I2 (buffer_write),
.I3 (buffer_read),
.I4 (full_int),
.I5 (1'b1),
.O5 (en_pointer),
.O6 (data_present_value));
(* HBLKNM = "uart_rx6_1" *)
FDR data_present_flop(
.D (data_present_value),
.Q (data_present_int),
.R (buffer_reset),
.C (clk));
(* HBLKNM = "uart_rx6_3" *)
LUT6_2 #(
.INIT (64'h0001000080000000))
full_lut(
.I0 (pointer[0]),
.I1 (pointer[1]),
.I2 (pointer[2]),
.I3 (pointer[3]),
.I4 (1'b1),
.I5 (1'b1),
.O5 (full_int),
.O6 (zero));
(* HBLKNM = "uart_rx6_4" *)
LUT6_2 #(
.INIT (64'hCCF00000AACC0000))
sample_lut(
.I0 (serial_in),
.I1 (sample),
.I2 (sample_dly),
.I3 (en_16_x_baud),
.I4 (1'b1),
.I5 (1'b1),
.O5 (sample_value),
.O6 (sample_dly_value));
(* HBLKNM = "uart_rx6_4" *)
FD sample_flop(
.D (sample_value),
.Q (sample),
.C (clk));
(* HBLKNM = "uart_rx6_4" *)
FD sample_dly_flop(
.D (sample_dly_value),
.Q (sample_dly),
.C (clk));
(* HBLKNM = "uart_rx6_4" *)
LUT6_2 #(
.INIT (64'hCAFFCAFF0000C0C0))
stop_bit_lut(
.I0 (stop_bit),
.I1 (sample),
.I2 (sample_input),
.I3 (run),
.I4 (data[0]),
.I5 (1'b1),
.O5 (buffer_write_value),
.O6 (stop_bit_value));
(* HBLKNM = "uart_rx6_4" *)
FD buffer_write_flop(
.D (buffer_write_value),
.Q (buffer_write),
.C (clk));
(* HBLKNM = "uart_rx6_4" *)
FD stop_bit_flop(
.D (stop_bit_value),
.Q (stop_bit),
.C (clk));
(* HBLKNM = "uart_rx6_2" *)
LUT6_2 #(
.INIT (64'hF0CCFFFFCCAAFFFF))
data01_lut(
.I0 (data[0]),
.I1 (data[1]),
.I2 (data[2]),
.I3 (sample_input),
.I4 (run),
.I5 (1'b1),
.O5 (data_value[0]),
.O6 (data_value[1]));
(* HBLKNM = "uart_rx6_2" *)
FD data0_flop(
.D (data_value[0]),
.Q (data[0]),
.C (clk));
(* HBLKNM = "uart_rx6_2" *)
FD data1_flop(
.D (data_value[1]),
.Q (data[1]),
.C (clk));
(* HBLKNM = "uart_rx6_2" *)
LUT6_2 #(
.INIT (64'hF0CCFFFFCCAAFFFF))
data23_lut(
.I0 (data[2]),
.I1 (data[3]),
.I2 (data[4]),
.I3 (sample_input),
.I4 (run),
.I5 (1'b1),
.O5 (data_value[2]),
.O6 (data_value[3]));
(* HBLKNM = "uart_rx6_2" *)
FD data2_flop(
.D (data_value[2]),
.Q (data[2]),
.C (clk));
(* HBLKNM = "uart_rx6_2" *)
FD data3_flop(
.D (data_value[3]),
.Q (data[3]),
.C (clk));
(* HBLKNM = "uart_rx6_2" *)
LUT6_2 #(
.INIT (64'hF0CCFFFFCCAAFFFF))
data45_lut(
.I0 (data[4]),
.I1 (data[5]),
.I2 (data[6]),
.I3 (sample_input),
.I4 (run),
.I5 (1'b1),
.O5 (data_value[4]),
.O6 (data_value[5]));
(* HBLKNM = "uart_rx6_2" *)
FD data4_flop(
.D (data_value[4]),
.Q (data[4]),
.C (clk));
(* HBLKNM = "uart_rx6_2" *)
FD data5_flop(
.D (data_value[5]),
.Q (data[5]),
.C (clk));
(* HBLKNM = "uart_rx6_2" *)
LUT6_2 #(
.INIT (64'hF0CCFFFFCCAAFFFF))
data67_lut(
.I0 (data[6]),
.I1 (data[7]),
.I2 (stop_bit),
.I3 (sample_input),
.I4 (run),
.I5 (1'b1),
.O5 (data_value[6]),
.O6 (data_value[7]));
(* HBLKNM = "uart_rx6_2" *)
FD data6_flop(
.D (data_value[6]),
.Q (data[6]),
.C (clk));
(* HBLKNM = "uart_rx6_2" *)
FD data7_flop(
.D (data_value[7]),
.Q (data[7]),
.C (clk));
(* HBLKNM = "uart_rx6_4" *)
LUT6 #(
.INIT (64'h2F2FAFAF0000FF00))
run_lut(
.I0 (data[0]),
.I1 (start_bit),
.I2 (sample_input),
.I3 (sample_dly),
.I4 (sample),
.I5 (run),
.O (run_value));
(* HBLKNM = "uart_rx6_4" *)
FD run_flop(
.D (run_value),
.Q (run),
.C (clk));
(* HBLKNM = "uart_rx6_4" *)
LUT6 #(
.INIT (64'h222200F000000000))
start_bit_lut(
.I0 (start_bit),
.I1 (sample_input),
.I2 (sample_dly),
.I3 (sample),
.I4 (run),
.I5 (1'b1),
.O (start_bit_value));
(* HBLKNM = "uart_rx6_4" *)
FD start_bit_flop(
.D (start_bit_value),
.Q (start_bit),
.C (clk));
(* HBLKNM = "uart_rx6_3" *)
LUT6_2 #(
.INIT (64'h6C0000005A000000))
div01_lut(
.I0 (div[0]),
.I1 (div[1]),
.I2 (en_16_x_baud),
.I3 (run),
.I4 (1'b1),
.I5 (1'b1),
.O5 (div_value[0]),
.O6 (div_value[1]));
(* HBLKNM = "uart_rx6_3" *)
FD div0_flop(
.D (div_value[0]),
.Q (div[0]),
.C (clk));
(* HBLKNM = "uart_rx6_3" *)
FD div1_flop(
.D (div_value[1]),
.Q (div[1]),
.C (clk));
(* HBLKNM = "uart_rx6_3" *)
LUT6_2 #(
.INIT (64'h6CCC00005AAA0000))
div23_lut(
.I0 (div[2]),
.I1 (div[3]),
.I2 (div_carry),
.I3 (en_16_x_baud),
.I4 (run),
.I5 (1'b1),
.O5 (div_value[2]),
.O6 (div_value[3]));
(* HBLKNM = "uart_rx6_3" *)
FD div2_flop(
.D (div_value[2]),
.Q (div[2]),
.C (clk));
(* HBLKNM = "uart_rx6_3" *)
FD div3_flop(
.D (div_value[3]),
.Q (div[3]),
.C (clk));
(* HBLKNM = "uart_rx6_3" *)
LUT6_2 #(
.INIT (64'h0080000088888888))
sample_input_lut(
.I0 (div[0]),
.I1 (div[1]),
.I2 (div[2]),
.I3 (div[3]),
.I4 (en_16_x_baud),
.I5 (1'b1),
.O5 (div_carry),
.O6 (sample_input_value));
(* HBLKNM = "uart_rx6_3" *)
FD sample_input_flop(
.D (sample_input_value),
.Q (sample_input),
.C (clk));
// assign internal wires to outputs
assign buffer_full = full_int;
assign buffer_half_full = pointer[3];
assign buffer_data_present = data_present_int;
endmodule
///////////////////////////////////////////////////////////////////////////////////////////
//
// END OF FILE uart_rx6.v
//
///////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,531 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2011, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
-- UART Receiver with integral 16 byte FIFO buffer
--
-- 8 bit, no parity, 1 stop bit
--
-- This module was made for use with Spartan-6 Generation Devices and is also ideally
-- suited for use with Virtex-6 and 7-Series devices.
--
-- Version 1 - 31st March 2011.
--
-- Ken Chapman
-- Xilinx Ltd
-- Benchmark House
-- 203 Brooklands Road
-- Weybridge
-- Surrey KT13 ORH
-- United Kingdom
--
-- chapman@xilinx.com
--
-------------------------------------------------------------------------------------------
--
-- Format of this file.
--
-- The module defines the implementation of the logic using Xilinx primitives.
-- These ensure predictable synthesis results and maximise the density of the
-- implementation. The Unisim Library is used to define Xilinx primitives. It is also
-- used during simulation.
-- The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
-------------------------------------------------------------------------------------------
--
-- Library declarations
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library unisim;
use unisim.vcomponents.all;
--
-------------------------------------------------------------------------------------------
--
-- Main Entity for
--
entity uart_rx6 is
Port ( serial_in : in std_logic;
en_16_x_baud : in std_logic;
data_out : out std_logic_vector(7 downto 0);
buffer_read : in std_logic;
buffer_data_present : out std_logic;
buffer_half_full : out std_logic;
buffer_full : out std_logic;
buffer_reset : in std_logic;
clk : in std_logic);
end uart_rx6;
--
-------------------------------------------------------------------------------------------
--
-- Start of Main Architecture for uart_rx6
--
architecture low_level_definition of uart_rx6 is
--
-------------------------------------------------------------------------------------------
--
-- Signals used in uart_rx6
--
-------------------------------------------------------------------------------------------
--
signal pointer_value : std_logic_vector(3 downto 0);
signal pointer : std_logic_vector(3 downto 0);
signal en_pointer : std_logic;
signal zero : std_logic;
signal full_int : std_logic;
signal data_present_value : std_logic;
signal data_present_int : std_logic;
signal sample_value : std_logic;
signal sample : std_logic;
signal sample_dly_value : std_logic;
signal sample_dly : std_logic;
signal stop_bit_value : std_logic;
signal stop_bit : std_logic;
signal data_value : std_logic_vector(7 downto 0);
signal data : std_logic_vector(7 downto 0);
signal run_value : std_logic;
signal run : std_logic;
signal start_bit_value : std_logic;
signal start_bit : std_logic;
signal div_value : std_logic_vector(3 downto 0);
signal div : std_logic_vector(3 downto 0);
signal div_carry : std_logic;
signal sample_input_value : std_logic;
signal sample_input : std_logic;
signal buffer_write_value : std_logic;
signal buffer_write : std_logic;
--
-------------------------------------------------------------------------------------------
--
-- Attributes to guide mapping of logic into Slices.
-------------------------------------------------------------------------------------------
--
--
attribute hblknm : string;
attribute hblknm of pointer3_lut : label is "uart_rx6_1";
attribute hblknm of pointer3_flop : label is "uart_rx6_1";
attribute hblknm of pointer2_lut : label is "uart_rx6_1";
attribute hblknm of pointer2_flop : label is "uart_rx6_1";
attribute hblknm of pointer01_lut : label is "uart_rx6_1";
attribute hblknm of pointer1_flop : label is "uart_rx6_1";
attribute hblknm of pointer0_flop : label is "uart_rx6_1";
attribute hblknm of data_present_lut : label is "uart_rx6_1";
attribute hblknm of data_present_flop : label is "uart_rx6_1";
--
attribute hblknm of data01_lut : label is "uart_rx6_2";
attribute hblknm of data0_flop : label is "uart_rx6_2";
attribute hblknm of data1_flop : label is "uart_rx6_2";
attribute hblknm of data23_lut : label is "uart_rx6_2";
attribute hblknm of data2_flop : label is "uart_rx6_2";
attribute hblknm of data3_flop : label is "uart_rx6_2";
attribute hblknm of data45_lut : label is "uart_rx6_2";
attribute hblknm of data4_flop : label is "uart_rx6_2";
attribute hblknm of data5_flop : label is "uart_rx6_2";
attribute hblknm of data67_lut : label is "uart_rx6_2";
attribute hblknm of data6_flop : label is "uart_rx6_2";
attribute hblknm of data7_flop : label is "uart_rx6_2";
--
attribute hblknm of div01_lut : label is "uart_rx6_3";
attribute hblknm of div23_lut : label is "uart_rx6_3";
attribute hblknm of div0_flop : label is "uart_rx6_3";
attribute hblknm of div1_flop : label is "uart_rx6_3";
attribute hblknm of div2_flop : label is "uart_rx6_3";
attribute hblknm of div3_flop : label is "uart_rx6_3";
attribute hblknm of sample_input_lut : label is "uart_rx6_3";
attribute hblknm of sample_input_flop : label is "uart_rx6_3";
attribute hblknm of full_lut : label is "uart_rx6_3";
--
attribute hblknm of sample_lut : label is "uart_rx6_4";
attribute hblknm of sample_flop : label is "uart_rx6_4";
attribute hblknm of sample_dly_flop : label is "uart_rx6_4";
attribute hblknm of stop_bit_lut : label is "uart_rx6_4";
attribute hblknm of stop_bit_flop : label is "uart_rx6_4";
attribute hblknm of buffer_write_flop : label is "uart_rx6_4";
attribute hblknm of start_bit_lut : label is "uart_rx6_4";
attribute hblknm of start_bit_flop : label is "uart_rx6_4";
attribute hblknm of run_lut : label is "uart_rx6_4";
attribute hblknm of run_flop : label is "uart_rx6_4";
--
--
-------------------------------------------------------------------------------------------
--
-- Start of uart_rx6 circuit description
--
-------------------------------------------------------------------------------------------
--
begin
-- SRL16E data storage
data_width_loop: for i in 0 to 7 generate
attribute hblknm : string;
attribute hblknm of storage_srl : label is "uart_rx6_5";
begin
storage_srl: SRL16E
generic map (INIT => X"0000")
port map( D => data(i),
CE => buffer_write,
CLK => clk,
A0 => pointer(0),
A1 => pointer(1),
A2 => pointer(2),
A3 => pointer(3),
Q => data_out(i) );
end generate data_width_loop;
pointer3_lut: LUT6
generic map (INIT => X"FF00FE00FF80FF00")
port map( I0 => pointer(0),
I1 => pointer(1),
I2 => pointer(2),
I3 => pointer(3),
I4 => buffer_write,
I5 => buffer_read,
O => pointer_value(3));
pointer3_flop: FDR
port map ( D => pointer_value(3),
Q => pointer(3),
R => buffer_reset,
C => clk);
pointer2_lut: LUT6
generic map (INIT => X"F0F0E1E0F878F0F0")
port map( I0 => pointer(0),
I1 => pointer(1),
I2 => pointer(2),
I3 => pointer(3),
I4 => buffer_write,
I5 => buffer_read,
O => pointer_value(2));
pointer2_flop: FDR
port map ( D => pointer_value(2),
Q => pointer(2),
R => buffer_reset,
C => clk);
pointer01_lut: LUT6_2
generic map (INIT => X"CC9060CCAA5050AA")
port map( I0 => pointer(0),
I1 => pointer(1),
I2 => en_pointer,
I3 => buffer_write,
I4 => buffer_read,
I5 => '1',
O5 => pointer_value(0),
O6 => pointer_value(1));
pointer1_flop: FDR
port map ( D => pointer_value(1),
Q => pointer(1),
R => buffer_reset,
C => clk);
pointer0_flop: FDR
port map ( D => pointer_value(0),
Q => pointer(0),
R => buffer_reset,
C => clk);
data_present_lut: LUT6_2
generic map (INIT => X"F4FCF4FC040004C0")
port map( I0 => zero,
I1 => data_present_int,
I2 => buffer_write,
I3 => buffer_read,
I4 => full_int,
I5 => '1',
O5 => en_pointer,
O6 => data_present_value);
data_present_flop: FDR
port map ( D => data_present_value,
Q => data_present_int,
R => buffer_reset,
C => clk);
full_lut: LUT6_2
generic map (INIT => X"0001000080000000")
port map( I0 => pointer(0),
I1 => pointer(1),
I2 => pointer(2),
I3 => pointer(3),
I4 => '1',
I5 => '1',
O5 => full_int,
O6 => zero);
sample_lut: LUT6_2
generic map (INIT => X"CCF00000AACC0000")
port map( I0 => serial_in,
I1 => sample,
I2 => sample_dly,
I3 => en_16_x_baud,
I4 => '1',
I5 => '1',
O5 => sample_value,
O6 => sample_dly_value);
sample_flop: FD
port map ( D => sample_value,
Q => sample,
C => clk);
sample_dly_flop: FD
port map ( D => sample_dly_value,
Q => sample_dly,
C => clk);
stop_bit_lut: LUT6_2
generic map (INIT => X"CAFFCAFF0000C0C0")
port map( I0 => stop_bit,
I1 => sample,
I2 => sample_input,
I3 => run,
I4 => data(0),
I5 => '1',
O5 => buffer_write_value,
O6 => stop_bit_value);
buffer_write_flop: FD
port map ( D => buffer_write_value,
Q => buffer_write,
C => clk);
stop_bit_flop: FD
port map ( D => stop_bit_value,
Q => stop_bit,
C => clk);
data01_lut: LUT6_2
generic map (INIT => X"F0CCFFFFCCAAFFFF")
port map( I0 => data(0),
I1 => data(1),
I2 => data(2),
I3 => sample_input,
I4 => run,
I5 => '1',
O5 => data_value(0),
O6 => data_value(1));
data0_flop: FD
port map ( D => data_value(0),
Q => data(0),
C => clk);
data1_flop: FD
port map ( D => data_value(1),
Q => data(1),
C => clk);
data23_lut: LUT6_2
generic map (INIT => X"F0CCFFFFCCAAFFFF")
port map( I0 => data(2),
I1 => data(3),
I2 => data(4),
I3 => sample_input,
I4 => run,
I5 => '1',
O5 => data_value(2),
O6 => data_value(3));
data2_flop: FD
port map ( D => data_value(2),
Q => data(2),
C => clk);
data3_flop: FD
port map ( D => data_value(3),
Q => data(3),
C => clk);
data45_lut: LUT6_2
generic map (INIT => X"F0CCFFFFCCAAFFFF")
port map( I0 => data(4),
I1 => data(5),
I2 => data(6),
I3 => sample_input,
I4 => run,
I5 => '1',
O5 => data_value(4),
O6 => data_value(5));
data4_flop: FD
port map ( D => data_value(4),
Q => data(4),
C => clk);
data5_flop: FD
port map ( D => data_value(5),
Q => data(5),
C => clk);
data67_lut: LUT6_2
generic map (INIT => X"F0CCFFFFCCAAFFFF")
port map( I0 => data(6),
I1 => data(7),
I2 => stop_bit,
I3 => sample_input,
I4 => run,
I5 => '1',
O5 => data_value(6),
O6 => data_value(7));
data6_flop: FD
port map ( D => data_value(6),
Q => data(6),
C => clk);
data7_flop: FD
port map ( D => data_value(7),
Q => data(7),
C => clk);
run_lut: LUT6
generic map (INIT => X"2F2FAFAF0000FF00")
port map( I0 => data(0),
I1 => start_bit,
I2 => sample_input,
I3 => sample_dly,
I4 => sample,
I5 => run,
O => run_value);
run_flop: FD
port map ( D => run_value,
Q => run,
C => clk);
start_bit_lut: LUT6
generic map (INIT => X"222200F000000000")
port map( I0 => start_bit,
I1 => sample_input,
I2 => sample_dly,
I3 => sample,
I4 => run,
I5 => '1',
O => start_bit_value);
start_bit_flop: FD
port map ( D => start_bit_value,
Q => start_bit,
C => clk);
div01_lut: LUT6_2
generic map (INIT => X"6C0000005A000000")
port map( I0 => div(0),
I1 => div(1),
I2 => en_16_x_baud,
I3 => run,
I4 => '1',
I5 => '1',
O5 => div_value(0),
O6 => div_value(1));
div0_flop: FD
port map ( D => div_value(0),
Q => div(0),
C => clk);
div1_flop: FD
port map ( D => div_value(1),
Q => div(1),
C => clk);
div23_lut: LUT6_2
generic map (INIT => X"6CCC00005AAA0000")
port map( I0 => div(2),
I1 => div(3),
I2 => div_carry,
I3 => en_16_x_baud,
I4 => run,
I5 => '1',
O5 => div_value(2),
O6 => div_value(3));
div2_flop: FD
port map ( D => div_value(2),
Q => div(2),
C => clk);
div3_flop: FD
port map ( D => div_value(3),
Q => div(3),
C => clk);
sample_input_lut: LUT6_2
generic map (INIT => X"0080000088888888")
port map( I0 => div(0),
I1 => div(1),
I2 => div(2),
I3 => div(3),
I4 => en_16_x_baud,
I5 => '1',
O5 => div_carry,
O6 => sample_input_value);
sample_input_flop: FD
port map ( D => sample_input_value,
Q => sample_input,
C => clk);
-- assign internal signals to outputs
buffer_full <= full_int;
buffer_half_full <= pointer(3);
buffer_data_present <= data_present_int;
end low_level_definition;
-------------------------------------------------------------------------------------------
--
-- END OF FILE uart_rx6.vhd
--
-------------------------------------------------------------------------------------------

View File

@ -0,0 +1,451 @@
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2011, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
// UART Transmitter with integral 16 byte FIFO buffer
//
// 8 bit, no parity, 1 stop bit
//
// This module was made for use with Spartan-6 Generation Devices and is also ideally
// suited for use with Virtex-6 and 7-Series devices.
//
// Version 1 - 8th July 2011.
// Derived from uart_tx6.vhd Version 1 (31st March 2011) by Nick Sawyer.
//
// Ken Chapman
// Xilinx Ltd
// Benchmark House
// 203 Brooklands Road
// Weybridge
// Surrey KT13 ORH
// United Kingdom
//
// chapman@xilinx.com
//
///////////////////////////////////////////////////////////////////////////////////////////
//
// Format of this file.
//
// The module defines the implementation of the logic using Xilinx primitives.
// These ensure predictable synthesis results and maximise the density of the
// implementation. The Unisim Library is used to define Xilinx primitives. It is also
// used during simulation.
// The source can be viewed at %XILINX%\verilog\src\unisims\
//
///////////////////////////////////////////////////////////////////////////////////////////
//
`timescale 1 ps / 1ps
module uart_tx6 (
input [7:0] data_in,
input buffer_write,
input buffer_reset,
input en_16_x_baud,
output serial_out,
output buffer_data_present,
output buffer_half_full,
output buffer_full,
input clk );
//
///////////////////////////////////////////////////////////////////////////////////////////
//
// wires used in uart_tx6
//
///////////////////////////////////////////////////////////////////////////////////////////
//
wire [7:0] store_data;
wire [7:0] data;
wire [3:0] pointer_value;
wire [3:0] pointer;
wire en_pointer;
wire zero;
wire full_int;
wire data_present_value;
wire data_present_int;
wire [3:0] sm_value;
wire [3:0] sm;
wire [3:0] div_value;
wire [3:0] div;
wire lsb_data;
wire msb_data;
wire last_bit;
wire serial_data;
wire next_value;
wire next_bit;
wire buffer_read_value;
wire buffer_read;
//
///////////////////////////////////////////////////////////////////////////////////////////
//
// Start of uart_tx6 circuit description
//
///////////////////////////////////////////////////////////////////////////////////////////
//
genvar i;
// SRL16E data storage
generate
for (i = 0 ; i <= 7 ; i = i+1)
begin : data_width_loop
(* HBLKNM = "uart_tx6_5" *)
SRL16E #(
.INIT (16'h0000))
storage_srl (
.D (data_in[i]),
.CE (buffer_write),
.CLK (clk),
.A0 (pointer[0]),
.A1 (pointer[1]),
.A2 (pointer[2]),
.A3 (pointer[3]),
.Q (store_data[i]));
(* HBLKNM = "uart_tx6_5" *)
FD storage_flop(
.D (store_data[i]),
.Q (data[i]),
.C (clk));
end //generate data_width_loop;
endgenerate
(* HBLKNM = "uart_tx6_1" *)
LUT6 #(
.INIT (64'hFF00FE00FF80FF00))
pointer3_lut(
.I0 (pointer[0]),
.I1 (pointer[1]),
.I2 (pointer[2]),
.I3 (pointer[3]),
.I4 (buffer_write),
.I5 (buffer_read),
.O (pointer_value[3]));
(* HBLKNM = "uart_tx6_1" *)
FDR pointer3_flop(
.D (pointer_value[3]),
.Q (pointer[3]),
.R (buffer_reset),
.C (clk));
(* HBLKNM = "uart_tx6_1" *)
LUT6 #(
.INIT (64'hF0F0E1E0F878F0F0))
pointer2_lut(
.I0 (pointer[0]),
.I1 (pointer[1]),
.I2 (pointer[2]),
.I3 (pointer[3]),
.I4 (buffer_write),
.I5 (buffer_read),
.O (pointer_value[2]));
(* HBLKNM = "uart_tx6_1" *)
FDR pointer2_flop(
.D (pointer_value[2]),
.Q (pointer[2]),
.R (buffer_reset),
.C (clk));
(* HBLKNM = "uart_tx6_1" *)
LUT6_2 #(
.INIT (64'hCC9060CCAA5050AA))
pointer01_lut(
.I0 (pointer[0]),
.I1 (pointer[1]),
.I2 (en_pointer),
.I3 (buffer_write),
.I4 (buffer_read),
.I5 (1'b1),
.O5 (pointer_value[0]),
.O6 (pointer_value[1]));
(* HBLKNM = "uart_tx6_1" *)
FDR pointer1_flop(
.D (pointer_value[1]),
.Q (pointer[1]),
.R (buffer_reset),
.C (clk));
(* HBLKNM = "uart_tx6_1" *)
FDR pointer0_flop(
.D (pointer_value[0]),
.Q (pointer[0]),
.R (buffer_reset),
.C (clk));
(* HBLKNM = "uart_tx6_1" *)
LUT6_2 #(
.INIT (64'hF4FCF4FC040004C0))
data_present_lut(
.I0 (zero),
.I1 (data_present_int),
.I2 (buffer_write),
.I3 (buffer_read),
.I4 (full_int),
.I5 (1'b1),
.O5 (en_pointer),
.O6 (data_present_value));
(* HBLKNM = "uart_tx6_1" *)
FDR data_present_flop(
.D (data_present_value),
.Q (data_present_int),
.R (buffer_reset),
.C (clk));
(* HBLKNM = "uart_tx6_4" *)
LUT6_2 #(
.INIT (64'h0001000080000000))
full_lut(
.I0 (pointer[0]),
.I1 (pointer[1]),
.I2 (pointer[2]),
.I3 (pointer[3]),
.I4 (1'b1),
.I5 (1'b1),
.O5 (full_int),
.O6 (zero));
(* HBLKNM = "uart_tx6_4" *)
LUT6 #(
.INIT (64'hFF00F0F0CCCCAAAA))
lsb_data_lut(
.I0 (data[0]),
.I1 (data[1]),
.I2 (data[2]),
.I3 (data[3]),
.I4 (sm[0]),
.I5 (sm[1]),
.O (lsb_data));
(* HBLKNM = "uart_tx6_4" *)
LUT6 #(
.INIT (64'hFF00F0F0CCCCAAAA))
msb_data_lut(
.I0 (data[4]),
.I1 (data[5]),
.I2 (data[6]),
.I3 (data[7]),
.I4 (sm[0]),
.I5 (sm[1]),
.O (msb_data));
(* HBLKNM = "uart_tx6_4" *)
LUT6_2 #(
.INIT (64'hCFAACC0F0FFFFFFF))
serial_lut(
.I0 (lsb_data),
.I1 (msb_data),
.I2 (sm[1]),
.I3 (sm[2]),
.I4 (sm[3]),
.I5 (1'b1),
.O5 (last_bit),
.O6 (serial_data));
(* HBLKNM = "uart_tx6_4" *)
FD serial_flop(
.D (serial_data),
.Q (serial_out),
.C (clk));
(* HBLKNM = "uart_tx6_2" *)
LUT6 #(
.INIT (64'h85500000AAAAAAAA))
sm0_lut(
.I0 (sm[0]),
.I1 (sm[1]),
.I2 (sm[2]),
.I3 (sm[3]),
.I4 (data_present_int),
.I5 (next_bit),
.O (sm_value[0]));
(* HBLKNM = "uart_tx6_2" *)
FD sm0_flop(
.D (sm_value[0]),
.Q (sm[0]),
.C (clk));
(* HBLKNM = "uart_tx6_2" *)
LUT6 #(
.INIT (64'h26610000CCCCCCCC))
sm1_lut(
.I0 (sm[0]),
.I1 (sm[1]),
.I2 (sm[2]),
.I3 (sm[3]),
.I4 (data_present_int),
.I5 (next_bit),
.O (sm_value[1]));
(* HBLKNM = "uart_tx6_2" *)
FD sm1_flop(
.D (sm_value[1]),
.Q (sm[1]),
.C (clk));
(* HBLKNM = "uart_tx6_2" *)
LUT6 #(
.INIT (64'h88700000F0F0F0F0))
sm2_lut(
.I0 (sm[0]),
.I1 (sm[1]),
.I2 (sm[2]),
.I3 (sm[3]),
.I4 (data_present_int),
.I5 (next_bit),
.O (sm_value[2]));
(* HBLKNM = "uart_tx6_2" *)
FD sm2_flop(
.D (sm_value[2]),
.Q (sm[2]),
.C (clk));
(* HBLKNM = "uart_tx6_2" *)
LUT6 #(
.INIT (64'h87440000FF00FF00))
sm3_lut(
.I0 (sm[0]),
.I1 (sm[1]),
.I2 (sm[2]),
.I3 (sm[3]),
.I4 (data_present_int),
.I5 (next_bit),
.O (sm_value[3]));
(* HBLKNM = "uart_tx6_2" *)
FD sm3_flop(
.D (sm_value[3]),
.Q (sm[3]),
.C (clk));
(* HBLKNM = "uart_tx6_3" *)
LUT6_2 #(
.INIT (64'h6C0000005A000000))
div01_lut(
.I0 (div[0]),
.I1 (div[1]),
.I2 (en_16_x_baud),
.I3 (1'b1),
.I4 (1'b1),
.I5 (1'b1),
.O5 (div_value[0]),
.O6 (div_value[1]));
(* HBLKNM = "uart_tx6_3" *)
FD div0_flop(
.D (div_value[0]),
.Q (div[0]),
.C (clk));
(* HBLKNM = "uart_tx6_3" *)
FD div1_flop(
.D (div_value[1]),
.Q (div[1]),
.C (clk));
(* HBLKNM = "uart_tx6_3" *)
LUT6_2 #(
.INIT (64'h7F80FF007878F0F0))
div23_lut(
.I0 (div[0]),
.I1 (div[1]),
.I2 (div[2]),
.I3 (div[3]),
.I4 (en_16_x_baud),
.I5 (1'b1),
.O5 (div_value[2]),
.O6 (div_value[3]));
(* HBLKNM = "uart_tx6_3" *)
FD div2_flop(
.D (div_value[2]),
.Q (div[2]),
.C (clk));
(* HBLKNM = "uart_tx6_3" *)
FD div3_flop(
.D (div_value[3]),
.Q (div[3]),
.C (clk));
(* HBLKNM = "uart_tx6_3" *)
LUT6_2 #(
.INIT (64'h0000000080000000))
next_lut(
.I0 (div[0]),
.I1 (div[1]),
.I2 (div[2]),
.I3 (div[3]),
.I4 (en_16_x_baud),
.I5 (last_bit),
.O5 (next_value),
.O6 (buffer_read_value));
(* HBLKNM = "uart_tx6_3" *)
FD next_flop(
.D (next_value),
.Q (next_bit),
.C (clk));
(* HBLKNM = "uart_tx6_3" *)
FD read_flop(
.D (buffer_read_value),
.Q (buffer_read),
.C (clk));
// assign internal wires to outputs
assign buffer_full = full_int;
assign buffer_half_full = pointer[3];
assign buffer_data_present = data_present_int;
endmodule
///////////////////////////////////////////////////////////////////////////////////////////
//
// END OF FILE uart_tx6.v
//
///////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,469 @@
--
-------------------------------------------------------------------------------------------
-- Copyright <20> 2011, Xilinx, Inc.
-- This file contains confidential and proprietary information of Xilinx, Inc. and is
-- protected under U.S. and international copyright and other intellectual property laws.
-------------------------------------------------------------------------------------------
--
-- Disclaimer:
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to
-- you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
-- MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
-- DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
-- OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
-- (whether in contract or tort, including negligence, or under any other theory
-- of liability) for any loss or damage of any kind or nature related to, arising
-- under or in connection with these materials, including for any direct, or any
-- indirect, special, incidental, or consequential loss or damage (including loss
-- of data, profits, goodwill, or any type of loss or damage suffered as a result
-- of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-safe, or for use in any
-- application requiring fail-safe performance, such as life-support or safety
-- devices or systems, Class III medical devices, nuclear facilities, applications
-- related to the deployment of airbags, or any other applications that could lead
-- to death, personal injury, or severe property or environmental damage
-- (individually and collectively, "Critical Applications"). Customer assumes the
-- sole risk and liability of any use of Xilinx products in Critical Applications,
-- subject only to applicable laws and regulations governing limitations on product
-- liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
-------------------------------------------------------------------------------------------
--
-- UART Transmitter with integral 16 byte FIFO buffer
--
-- 8 bit, no parity, 1 stop bit
--
-- This module was made for use with Spartan-6 Generation Devices and is also ideally
-- suited for use with Virtex-6 and 7-Series devices.
--
-- Version 1 - 31st March 2011.
--
-- Ken Chapman
-- Xilinx Ltd
-- Benchmark House
-- 203 Brooklands Road
-- Weybridge
-- Surrey KT13 ORH
-- United Kingdom
--
-- chapman@xilinx.com
--
-------------------------------------------------------------------------------------------
--
-- Format of this file.
--
-- The module defines the implementation of the logic using Xilinx primitives.
-- These ensure predictable synthesis results and maximise the density of the
-- implementation. The Unisim Library is used to define Xilinx primitives. It is also
-- used during simulation.
-- The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--
-------------------------------------------------------------------------------------------
--
-- Library declarations
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library unisim;
use unisim.vcomponents.all;
--
-------------------------------------------------------------------------------------------
--
-- Main Entity for
--
entity uart_tx6 is
Port ( data_in : in std_logic_vector(7 downto 0);
en_16_x_baud : in std_logic;
serial_out : out std_logic;
buffer_write : in std_logic;
buffer_data_present : out std_logic;
buffer_half_full : out std_logic;
buffer_full : out std_logic;
buffer_reset : in std_logic;
clk : in std_logic);
end uart_tx6;
--
-------------------------------------------------------------------------------------------
--
-- Start of Main Architecture for uart_tx6
--
architecture low_level_definition of uart_tx6 is
--
-------------------------------------------------------------------------------------------
--
-- Signals used in uart_tx6
--
-------------------------------------------------------------------------------------------
--
signal store_data : std_logic_vector(7 downto 0);
signal data : std_logic_vector(7 downto 0);
signal pointer_value : std_logic_vector(3 downto 0);
signal pointer : std_logic_vector(3 downto 0);
signal en_pointer : std_logic;
signal zero : std_logic;
signal full_int : std_logic;
signal data_present_value : std_logic;
signal data_present_int : std_logic;
signal sm_value : std_logic_vector(3 downto 0);
signal sm : std_logic_vector(3 downto 0);
signal div_value : std_logic_vector(3 downto 0);
signal div : std_logic_vector(3 downto 0);
signal lsb_data : std_logic;
signal msb_data : std_logic;
signal last_bit : std_logic;
signal serial_data : std_logic;
signal next_value : std_logic;
signal next_bit : std_logic;
signal buffer_read_value : std_logic;
signal buffer_read : std_logic;
--
-------------------------------------------------------------------------------------------
--
-- Attributes to guide mapping of logic into Slices.
-------------------------------------------------------------------------------------------
--
--
attribute hblknm : string;
attribute hblknm of pointer3_lut : label is "uart_tx6_1";
attribute hblknm of pointer3_flop : label is "uart_tx6_1";
attribute hblknm of pointer2_lut : label is "uart_tx6_1";
attribute hblknm of pointer2_flop : label is "uart_tx6_1";
attribute hblknm of pointer01_lut : label is "uart_tx6_1";
attribute hblknm of pointer1_flop : label is "uart_tx6_1";
attribute hblknm of pointer0_flop : label is "uart_tx6_1";
attribute hblknm of data_present_lut : label is "uart_tx6_1";
attribute hblknm of data_present_flop : label is "uart_tx6_1";
--
attribute hblknm of sm0_lut : label is "uart_tx6_2";
attribute hblknm of sm0_flop : label is "uart_tx6_2";
attribute hblknm of sm1_lut : label is "uart_tx6_2";
attribute hblknm of sm1_flop : label is "uart_tx6_2";
attribute hblknm of sm2_lut : label is "uart_tx6_2";
attribute hblknm of sm2_flop : label is "uart_tx6_2";
attribute hblknm of sm3_lut : label is "uart_tx6_2";
attribute hblknm of sm3_flop : label is "uart_tx6_2";
--
attribute hblknm of div01_lut : label is "uart_tx6_3";
attribute hblknm of div23_lut : label is "uart_tx6_3";
attribute hblknm of div0_flop : label is "uart_tx6_3";
attribute hblknm of div1_flop : label is "uart_tx6_3";
attribute hblknm of div2_flop : label is "uart_tx6_3";
attribute hblknm of div3_flop : label is "uart_tx6_3";
attribute hblknm of next_lut : label is "uart_tx6_3";
attribute hblknm of next_flop : label is "uart_tx6_3";
attribute hblknm of read_flop : label is "uart_tx6_3";
--
attribute hblknm of lsb_data_lut : label is "uart_tx6_4";
attribute hblknm of msb_data_lut : label is "uart_tx6_4";
attribute hblknm of serial_lut : label is "uart_tx6_4";
attribute hblknm of serial_flop : label is "uart_tx6_4";
attribute hblknm of full_lut : label is "uart_tx6_4";
--
--
-------------------------------------------------------------------------------------------
--
-- Start of uart_tx6 circuit description
--
-------------------------------------------------------------------------------------------
--
begin
-- SRL16E data storage
data_width_loop: for i in 0 to 7 generate
attribute hblknm : string;
attribute hblknm of storage_srl : label is "uart_tx6_5";
attribute hblknm of storage_flop : label is "uart_tx6_5";
begin
storage_srl: SRL16E
generic map (INIT => X"0000")
port map( D => data_in(i),
CE => buffer_write,
CLK => clk,
A0 => pointer(0),
A1 => pointer(1),
A2 => pointer(2),
A3 => pointer(3),
Q => store_data(i) );
storage_flop: FD
port map ( D => store_data(i),
Q => data(i),
C => clk);
end generate data_width_loop;
pointer3_lut: LUT6
generic map (INIT => X"FF00FE00FF80FF00")
port map( I0 => pointer(0),
I1 => pointer(1),
I2 => pointer(2),
I3 => pointer(3),
I4 => buffer_write,
I5 => buffer_read,
O => pointer_value(3));
pointer3_flop: FDR
port map ( D => pointer_value(3),
Q => pointer(3),
R => buffer_reset,
C => clk);
pointer2_lut: LUT6
generic map (INIT => X"F0F0E1E0F878F0F0")
port map( I0 => pointer(0),
I1 => pointer(1),
I2 => pointer(2),
I3 => pointer(3),
I4 => buffer_write,
I5 => buffer_read,
O => pointer_value(2));
pointer2_flop: FDR
port map ( D => pointer_value(2),
Q => pointer(2),
R => buffer_reset,
C => clk);
pointer01_lut: LUT6_2
generic map (INIT => X"CC9060CCAA5050AA")
port map( I0 => pointer(0),
I1 => pointer(1),
I2 => en_pointer,
I3 => buffer_write,
I4 => buffer_read,
I5 => '1',
O5 => pointer_value(0),
O6 => pointer_value(1));
pointer1_flop: FDR
port map ( D => pointer_value(1),
Q => pointer(1),
R => buffer_reset,
C => clk);
pointer0_flop: FDR
port map ( D => pointer_value(0),
Q => pointer(0),
R => buffer_reset,
C => clk);
data_present_lut: LUT6_2
generic map (INIT => X"F4FCF4FC040004C0")
port map( I0 => zero,
I1 => data_present_int,
I2 => buffer_write,
I3 => buffer_read,
I4 => full_int,
I5 => '1',
O5 => en_pointer,
O6 => data_present_value);
data_present_flop: FDR
port map ( D => data_present_value,
Q => data_present_int,
R => buffer_reset,
C => clk);
full_lut: LUT6_2
generic map (INIT => X"0001000080000000")
port map( I0 => pointer(0),
I1 => pointer(1),
I2 => pointer(2),
I3 => pointer(3),
I4 => '1',
I5 => '1',
O5 => full_int,
O6 => zero);
lsb_data_lut: LUT6
generic map (INIT => X"FF00F0F0CCCCAAAA")
port map( I0 => data(0),
I1 => data(1),
I2 => data(2),
I3 => data(3),
I4 => sm(0),
I5 => sm(1),
O => lsb_data);
msb_data_lut: LUT6
generic map (INIT => X"FF00F0F0CCCCAAAA")
port map( I0 => data(4),
I1 => data(5),
I2 => data(6),
I3 => data(7),
I4 => sm(0),
I5 => sm(1),
O => msb_data);
serial_lut: LUT6_2
generic map (INIT => X"CFAACC0F0FFFFFFF")
port map( I0 => lsb_data,
I1 => msb_data,
I2 => sm(1),
I3 => sm(2),
I4 => sm(3),
I5 => '1',
O5 => last_bit,
O6 => serial_data);
serial_flop: FD
port map ( D => serial_data,
Q => serial_out,
C => clk);
sm0_lut: LUT6
generic map (INIT => X"85500000AAAAAAAA")
port map( I0 => sm(0),
I1 => sm(1),
I2 => sm(2),
I3 => sm(3),
I4 => data_present_int,
I5 => next_bit,
O => sm_value(0));
sm0_flop: FD
port map ( D => sm_value(0),
Q => sm(0),
C => clk);
sm1_lut: LUT6
generic map (INIT => X"26610000CCCCCCCC")
port map( I0 => sm(0),
I1 => sm(1),
I2 => sm(2),
I3 => sm(3),
I4 => data_present_int,
I5 => next_bit,
O => sm_value(1));
sm1_flop: FD
port map ( D => sm_value(1),
Q => sm(1),
C => clk);
sm2_lut: LUT6
generic map (INIT => X"88700000F0F0F0F0")
port map( I0 => sm(0),
I1 => sm(1),
I2 => sm(2),
I3 => sm(3),
I4 => data_present_int,
I5 => next_bit,
O => sm_value(2));
sm2_flop: FD
port map ( D => sm_value(2),
Q => sm(2),
C => clk);
sm3_lut: LUT6
generic map (INIT => X"87440000FF00FF00")
port map( I0 => sm(0),
I1 => sm(1),
I2 => sm(2),
I3 => sm(3),
I4 => data_present_int,
I5 => next_bit,
O => sm_value(3));
sm3_flop: FD
port map ( D => sm_value(3),
Q => sm(3),
C => clk);
div01_lut: LUT6_2
generic map (INIT => X"6C0000005A000000")
port map( I0 => div(0),
I1 => div(1),
I2 => en_16_x_baud,
I3 => '1',
I4 => '1',
I5 => '1',
O5 => div_value(0),
O6 => div_value(1));
div0_flop: FD
port map ( D => div_value(0),
Q => div(0),
C => clk);
div1_flop: FD
port map ( D => div_value(1),
Q => div(1),
C => clk);
div23_lut: LUT6_2
generic map (INIT => X"7F80FF007878F0F0")
port map( I0 => div(0),
I1 => div(1),
I2 => div(2),
I3 => div(3),
I4 => en_16_x_baud,
I5 => '1',
O5 => div_value(2),
O6 => div_value(3));
div2_flop: FD
port map ( D => div_value(2),
Q => div(2),
C => clk);
div3_flop: FD
port map ( D => div_value(3),
Q => div(3),
C => clk);
next_lut: LUT6_2
generic map (INIT => X"0000000080000000")
port map( I0 => div(0),
I1 => div(1),
I2 => div(2),
I3 => div(3),
I4 => en_16_x_baud,
I5 => last_bit,
O5 => next_value,
O6 => buffer_read_value);
next_flop: FD
port map ( D => next_value,
Q => next_bit,
C => clk);
read_flop: FD
port map ( D => buffer_read_value,
Q => buffer_read,
C => clk);
-- assign internal signals to outputs
buffer_full <= full_int;
buffer_half_full <= pointer(3);
buffer_data_present <= data_present_int;
end low_level_definition;
-------------------------------------------------------------------------------------------
--
-- END OF FILE uart_tx6.vhd
--
-------------------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,354 @@
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2010-2013, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
ROM_form.v
Production template for a 0.25K program (256 instructions) for KCPSM6 in a Spartan-6,
Virtex-6 or 7-Series device using 18 Slices.
Nick Sawyer (Xilinx Ltd)
Ken Chapman (Xilinx Ltd)
14th March 2013 - First Release
This is a verilog template file for the KCPSM6 assembler.
This verilog file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.v' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the verilog.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2010-2013, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
//
// Production definition of a 0.25K program (256 instructions) for KCPSM6 in a Spartan-6,
// Virtex-6 or 7-Series device using 18 Slices.
//
// Note: The full 12-bit KCPSM6 address is connected but only the lower 8-bits will be
// employed. Likewise the 'bram_enable' should still be connected to 'enable'.
// This minimises the changes required to the hardware description of a design
// when moving between different memory types and selecting different sizes.
//
//
// Program defined by '{psmname}.psm'.
//
// Generated by KCPSM6 Assembler: {timestamp}.
//
// Assembler used ROM_form template: ROM_form_128_14March13.v
//
//
`timescale 1ps/1ps
//
//
module {name} (
input [11:0] address,
output [17:0] instruction,
input enable,
input clk );
//
//
wire [17:0] rom_value;
//
//
genvar i;
generate
for (i = 0; i <= 17; i = i+1)
begin : instruction_bit
//
FDRE kcpsm6_rom_flop ( .D (rom_value[i]),
.Q (instruction[i]),
.CE (enable),
.R (address[7+(i/4)]),
.C (clk));
end
endgenerate
//
//
ROM128X1
#( .INIT (256'h{INIT128_0}))
kcpsm6_rom0( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[0]));
//
ROM128X1
#( .INIT (256'h{INIT128_1}))
kcpsm6_rom1( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[1]));
//
ROM128X1
#( .INIT (256'h{INIT128_2}))
kcpsm6_rom2( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[2]));
//
ROM128X1
#( .INIT (256'h{INIT128_3}))
kcpsm6_rom3( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[3]));
//
ROM128X1
#( .INIT (256'h{INIT128_4}))
kcpsm6_rom4( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[4]));
//
ROM128X1
#( .INIT (256'h{INIT128_5}))
kcpsm6_rom5( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[5]));
//
ROM128X1
#( .INIT (256'h{INIT128_6}))
kcpsm6_rom6( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[6]));
//
ROM128X1
#( .INIT (256'h{INIT128_7}))
kcpsm6_rom7( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[7]));
//
ROM128X1
#( .INIT (256'h{INIT128_8}))
kcpsm6_rom8( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[8]));
//
ROM128X1
#( .INIT (256'h{INIT128_9}))
kcpsm6_rom9( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[9]));
//
ROM128X1
#( .INIT (256'h{INIT128_10}))
kcpsm6_rom10( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[10]));
//
ROM128X1
#( .INIT (256'h{INIT128_11}))
kcpsm6_rom11( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[11]));
//
ROM128X1
#( .INIT (256'h{INIT128_12}))
kcpsm6_rom12( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[12]));
//
ROM128X1
#( .INIT (256'h{INIT128_13}))
kcpsm6_rom13( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[13]));
//
ROM128X1
#( .INIT (256'h{INIT128_14}))
kcpsm6_rom14( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[14]));
//
ROM128X1
#( .INIT (256'h{INIT128_15}))
kcpsm6_rom15( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[15]));
//
ROM128X1
#( .INIT (256'h{INIT128_16}))
kcpsm6_rom16( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[16]));
//
ROM128X1
#( .INIT (256'h{INIT128_17}))
kcpsm6_rom17( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.O (rom_value[17]));
//
//
endmodule
//
////////////////////////////////////////////////////////////////////////////////////
//
// END OF FILE {name}.v
//
////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,369 @@
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2010-2011, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
ROM_form.v
Production template for a 0.25K program (256 instructions) for KCPSM6 in a Spartan-6,
Virtex-6 or 7-Series device using 18 Slices.
Nick Sawyer (Xilinx Ltd)
Ken Chapman (Xilinx Ltd)
5th August 2011
This is a verilog template file for the KCPSM6 assembler.
This verilog file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.v' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the verilog.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2010-2011, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
//
// Production definition of a 0.25K program (256 instructions) for KCPSM6 in a Spartan-6,
// Virtex-6 or 7-Series device using 18 Slices.
//
// Note: The full 12-bit KCPSM6 address is connected but only the lower 8-bits will be
// employed. Likewise the 'bram_enable' should still be connected to 'enable'.
// This minimises the changes required to the hardware description of a design
// when moving between different memory types and selecting different sizes.
//
//
// Program defined by '{psmname}.psm'.
//
// Generated by KCPSM6 Assembler: {timestamp}.
//
`timescale 1ps/1ps
//
//
module {name} (
input [11:0] address,
output [17:0] instruction,
input enable,
input clk );
//
//
wire [17:0] rom_value;
//
//
genvar i;
generate
for (i = 0; i <= 17; i = i+1)
begin : instruction_bit
//
FDRE kcpsm6_rom_flop ( .D (rom_value[i]),
.Q (instruction[i]),
.CE (enable),
.R (address[8+(i/5)]),
.C (clk));
end
endgenerate
//
//
ROM256X1
#( .INIT (256'h{INIT256_0}))
kcpsm6_rom0( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[0]));
//
ROM256X1
#( .INIT (256'h{INIT256_1}))
kcpsm6_rom1( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[1]));
//
ROM256X1
#( .INIT (256'h{INIT256_2}))
kcpsm6_rom2( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[2]));
//
ROM256X1
#( .INIT (256'h{INIT256_3}))
kcpsm6_rom3( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[3]));
//
ROM256X1
#( .INIT (256'h{INIT256_4}))
kcpsm6_rom4( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[4]));
//
ROM256X1
#( .INIT (256'h{INIT256_5}))
kcpsm6_rom5( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[5]));
//
ROM256X1
#( .INIT (256'h{INIT256_6}))
kcpsm6_rom6( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[6]));
//
ROM256X1
#( .INIT (256'h{INIT256_7}))
kcpsm6_rom7( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[7]));
//
ROM256X1
#( .INIT (256'h{INIT256_8}))
kcpsm6_rom8( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[8]));
//
ROM256X1
#( .INIT (256'h{INIT256_9}))
kcpsm6_rom9( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[9]));
//
ROM256X1
#( .INIT (256'h{INIT256_10}))
kcpsm6_rom10( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[10]));
//
ROM256X1
#( .INIT (256'h{INIT256_11}))
kcpsm6_rom11( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[11]));
//
ROM256X1
#( .INIT (256'h{INIT256_12}))
kcpsm6_rom12( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[12]));
//
ROM256X1
#( .INIT (256'h{INIT256_13}))
kcpsm6_rom13( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[13]));
//
ROM256X1
#( .INIT (256'h{INIT256_14}))
kcpsm6_rom14( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[14]));
//
ROM256X1
#( .INIT (256'h{INIT256_15}))
kcpsm6_rom15( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[15]));
//
ROM256X1
#( .INIT (256'h{INIT256_16}))
kcpsm6_rom16( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[16]));
//
ROM256X1
#( .INIT (256'h{INIT256_17}))
kcpsm6_rom17( .A0 (address[0]),
.A1 (address[1]),
.A2 (address[2]),
.A3 (address[3]),
.A4 (address[4]),
.A5 (address[5]),
.A6 (address[6]),
.A7 (address[7]),
.O (rom_value[17]));
//
//
endmodule
//
////////////////////////////////////////////////////////////////////////////////////
//
// END OF FILE {name}.v
//
////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,273 @@
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2010-2013, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
ROM_form.v
Production template for a 1K program for KCPSM6 in a 7-Series device using a
RAMB18E1 primitive.
Nick Sawyer (Xilinx Ltd)
Ken Chapman (Xilinx Ltd)
5th August 2011 - First Release
14th March 2013 - Unused address inputs on BRAMs connected High to reflect
descriptions UG473.
This is a verilog template file for the KCPSM6 assembler.
This verilog file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.v' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the verilog.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2010-2013, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
//
// Production definition of a 1K program for KCPSM6 in a 7-Series device using a
// RAMB18E1 primitive.
//
// Note: The complete 12-bit address bus is connected to KCPSM6 to facilitate future code
// expansion with minimum changes being required to the hardware description.
// Only the lower 10-bits of the address are actually used for the 1K address range
// 000 to 3FF hex.
//
// Program defined by '{psmname}.psm'.
//
// Generated by KCPSM6 Assembler: {timestamp}.
//
// Assembler used ROM_form template: ROM_form_7S_1K_14March13.v
//
//
module {name} (
input [11:0] address,
output [17:0] instruction,
input enable,
input clk);
//
//
wire [13:0] address_a;
wire [17:0] data_in_a;
wire [17:0] data_out_a;
wire [13:0] address_b;
wire [17:0] data_in_b;
wire [17:0] data_out_b;
wire enable_b;
wire clk_b;
wire [3:0] we_b;
//
//
assign address_a = {address[9:0], 4'b1111};
assign instruction = data_out_a[17:0];
assign data_in_a = {16'h0000, address[11:10]};
//
assign address_b = 14'b11111111111111;
assign data_in_b = data_out_b[17:0];
assign enable_b = 1'b0;
assign we_b = 4'h0;
assign clk_b = 1'b0;
//
//
RAMB18E1 # ( .READ_WIDTH_A (18),
.WRITE_WIDTH_A (18),
.DOA_REG (0),
.INIT_A (16'b000000000000000000),
.RSTREG_PRIORITY_A ("REGCE"),
.SRVAL_A (36'h000000000000000000),
.WRITE_MODE_A ("WRITE_FIRST"),
.READ_WIDTH_B (18),
.WRITE_WIDTH_B (18),
.DOB_REG (0),
.INIT_B (36'h000000000000000000),
.RSTREG_PRIORITY_B ("REGCE"),
.SRVAL_B (36'h000000000000000000),
.WRITE_MODE_B ("WRITE_FIRST"),
.INIT_FILE ("NONE"),
.SIM_COLLISION_CHECK ("ALL"),
.RAM_MODE ("TDP"),
.RDADDR_COLLISION_HWCONFIG ("DELAYED_WRITE"),
.SIM_DEVICE ("7SERIES"),
.INIT_00 (256'h{INIT_00}),
.INIT_01 (256'h{INIT_01}),
.INIT_02 (256'h{INIT_02}),
.INIT_03 (256'h{INIT_03}),
.INIT_04 (256'h{INIT_04}),
.INIT_05 (256'h{INIT_05}),
.INIT_06 (256'h{INIT_06}),
.INIT_07 (256'h{INIT_07}),
.INIT_08 (256'h{INIT_08}),
.INIT_09 (256'h{INIT_09}),
.INIT_0A (256'h{INIT_0A}),
.INIT_0B (256'h{INIT_0B}),
.INIT_0C (256'h{INIT_0C}),
.INIT_0D (256'h{INIT_0D}),
.INIT_0E (256'h{INIT_0E}),
.INIT_0F (256'h{INIT_0F}),
.INIT_10 (256'h{INIT_10}),
.INIT_11 (256'h{INIT_11}),
.INIT_12 (256'h{INIT_12}),
.INIT_13 (256'h{INIT_13}),
.INIT_14 (256'h{INIT_14}),
.INIT_15 (256'h{INIT_15}),
.INIT_16 (256'h{INIT_16}),
.INIT_17 (256'h{INIT_17}),
.INIT_18 (256'h{INIT_18}),
.INIT_19 (256'h{INIT_19}),
.INIT_1A (256'h{INIT_1A}),
.INIT_1B (256'h{INIT_1B}),
.INIT_1C (256'h{INIT_1C}),
.INIT_1D (256'h{INIT_1D}),
.INIT_1E (256'h{INIT_1E}),
.INIT_1F (256'h{INIT_1F}),
.INIT_20 (256'h{INIT_20}),
.INIT_21 (256'h{INIT_21}),
.INIT_22 (256'h{INIT_22}),
.INIT_23 (256'h{INIT_23}),
.INIT_24 (256'h{INIT_24}),
.INIT_25 (256'h{INIT_25}),
.INIT_26 (256'h{INIT_26}),
.INIT_27 (256'h{INIT_27}),
.INIT_28 (256'h{INIT_28}),
.INIT_29 (256'h{INIT_29}),
.INIT_2A (256'h{INIT_2A}),
.INIT_2B (256'h{INIT_2B}),
.INIT_2C (256'h{INIT_2C}),
.INIT_2D (256'h{INIT_2D}),
.INIT_2E (256'h{INIT_2E}),
.INIT_2F (256'h{INIT_2F}),
.INIT_30 (256'h{INIT_30}),
.INIT_31 (256'h{INIT_31}),
.INIT_32 (256'h{INIT_32}),
.INIT_33 (256'h{INIT_33}),
.INIT_34 (256'h{INIT_34}),
.INIT_35 (256'h{INIT_35}),
.INIT_36 (256'h{INIT_36}),
.INIT_37 (256'h{INIT_37}),
.INIT_38 (256'h{INIT_38}),
.INIT_39 (256'h{INIT_39}),
.INIT_3A (256'h{INIT_3A}),
.INIT_3B (256'h{INIT_3B}),
.INIT_3C (256'h{INIT_3C}),
.INIT_3D (256'h{INIT_3D}),
.INIT_3E (256'h{INIT_3E}),
.INIT_3F (256'h{INIT_3F}),
.INITP_00 (256'h{INITP_00}),
.INITP_01 (256'h{INITP_01}),
.INITP_02 (256'h{INITP_02}),
.INITP_03 (256'h{INITP_03}),
.INITP_04 (256'h{INITP_04}),
.INITP_05 (256'h{INITP_05}),
.INITP_06 (256'h{INITP_06}),
.INITP_07 (256'h{INITP_07}))
kcpsm6_rom( .ADDRARDADDR (address_a),
.ENARDEN (enable),
.CLKARDCLK (clk),
.DOADO (data_out_a[15:0]),
.DOPADOP (data_out_a[17:16]),
.DIADI (data_in_a[15:0]),
.DIPADIP (data_in_a[17:16]),
.WEA (2'b00),
.REGCEAREGCE (1'b0),
.RSTRAMARSTRAM (1'b0),
.RSTREGARSTREG (1'b0),
.ADDRBWRADDR (address_b),
.ENBWREN (enable_b),
.CLKBWRCLK (clk_b),
.DOBDO (data_out_b[15:0]),
.DOPBDOP (data_out_b[17:16]),
.DIBDI (data_in_b[15:0]),
.DIPBDIP (data_in_b[17:16]),
.WEBWE (we_b),
.REGCEB (1'b0),
.RSTRAMB (1'b0),
.RSTREGB (1'b0));
//
//
endmodule
//
////////////////////////////////////////////////////////////////////////////////////
//
// END OF FILE {name}.v
//
////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,358 @@
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2010-2013, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
ROM_form.v
Production template for a 2K program for KCPSM6 in a 7-Series device using a
RAMB36E1 primitive.
Nick Sawyer (Xilinx Ltd)
Ken Chapman (Xilinx Ltd)
5th August 2011 - First Release
14th March 2013 - Unused address inputs on BRAMs connected High to reflect
descriptions UG473.
This is a verilog template file for the KCPSM6 assembler.
This verilog file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.v' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the verilog.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2010-2013, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
//
// Production definition of a 2K program for KCPSM6 in a 7-Series device using a
// RAMB36E1 primitive.
//
// Note: The complete 12-bit address bus is connected to KCPSM6 to facilitate future code
// expansion with minimum changes being required to the hardware description.
// Only the lower 11-bits of the address are actually used for the 2K address range
// 000 to 7FF hex.
//
// Program defined by '{psmname}.psm'.
//
// Generated by KCPSM6 Assembler: {timestamp}.
//
// Assembler used ROM_form template: ROM_form_7S_2K_14March13.v
//
//
module {name} (
input [11:0] address,
output [17:0] instruction,
input enable,
input clk);
//
//
wire [15:0] address_a;
wire [35:0] data_in_a;
wire [35:0] data_out_a;
wire [15:0] address_b;
wire [35:0] data_in_b;
wire [35:0] data_out_b;
wire enable_b;
wire clk_b;
wire [7:0] we_b;
//
//
assign address_a = {1'b1, address[10:0], 4'b1111};
assign instruction = {data_out_a[33:32], data_out_a[15:0]};
assign data_in_a = {35'b000000000000000000000000000000000000, address[11]};
//
assign address_b = 16'b1111111111111111;
assign data_in_b = {2'h0, data_out_b[33:32], 16'h0000, data_out_b[15:0]};
assign enable_b = 1'b0;
assign we_b = 8'h00;
assign clk_b = 1'b0;
//
RAMB36E1 # ( .READ_WIDTH_A (18),
.WRITE_WIDTH_A (18),
.DOA_REG (0),
.INIT_A (36'h000000000),
.RSTREG_PRIORITY_A ("REGCE"),
.SRVAL_A (36'h000000000),
.WRITE_MODE_A ("WRITE_FIRST"),
.READ_WIDTH_B (18),
.WRITE_WIDTH_B (18),
.DOB_REG (0),
.INIT_B (36'h000000000),
.RSTREG_PRIORITY_B ("REGCE"),
.SRVAL_B (36'h000000000),
.WRITE_MODE_B ("WRITE_FIRST"),
.INIT_FILE ("NONE"),
.SIM_COLLISION_CHECK ("ALL"),
.RAM_MODE ("TDP"),
.RDADDR_COLLISION_HWCONFIG ("DELAYED_WRITE"),
.EN_ECC_READ ("FALSE"),
.EN_ECC_WRITE ("FALSE"),
.RAM_EXTENSION_A ("NONE"),
.RAM_EXTENSION_B ("NONE"),
.SIM_DEVICE ("7SERIES"),
.INIT_00 (256'h{INIT_00}),
.INIT_01 (256'h{INIT_01}),
.INIT_02 (256'h{INIT_02}),
.INIT_03 (256'h{INIT_03}),
.INIT_04 (256'h{INIT_04}),
.INIT_05 (256'h{INIT_05}),
.INIT_06 (256'h{INIT_06}),
.INIT_07 (256'h{INIT_07}),
.INIT_08 (256'h{INIT_08}),
.INIT_09 (256'h{INIT_09}),
.INIT_0A (256'h{INIT_0A}),
.INIT_0B (256'h{INIT_0B}),
.INIT_0C (256'h{INIT_0C}),
.INIT_0D (256'h{INIT_0D}),
.INIT_0E (256'h{INIT_0E}),
.INIT_0F (256'h{INIT_0F}),
.INIT_10 (256'h{INIT_10}),
.INIT_11 (256'h{INIT_11}),
.INIT_12 (256'h{INIT_12}),
.INIT_13 (256'h{INIT_13}),
.INIT_14 (256'h{INIT_14}),
.INIT_15 (256'h{INIT_15}),
.INIT_16 (256'h{INIT_16}),
.INIT_17 (256'h{INIT_17}),
.INIT_18 (256'h{INIT_18}),
.INIT_19 (256'h{INIT_19}),
.INIT_1A (256'h{INIT_1A}),
.INIT_1B (256'h{INIT_1B}),
.INIT_1C (256'h{INIT_1C}),
.INIT_1D (256'h{INIT_1D}),
.INIT_1E (256'h{INIT_1E}),
.INIT_1F (256'h{INIT_1F}),
.INIT_20 (256'h{INIT_20}),
.INIT_21 (256'h{INIT_21}),
.INIT_22 (256'h{INIT_22}),
.INIT_23 (256'h{INIT_23}),
.INIT_24 (256'h{INIT_24}),
.INIT_25 (256'h{INIT_25}),
.INIT_26 (256'h{INIT_26}),
.INIT_27 (256'h{INIT_27}),
.INIT_28 (256'h{INIT_28}),
.INIT_29 (256'h{INIT_29}),
.INIT_2A (256'h{INIT_2A}),
.INIT_2B (256'h{INIT_2B}),
.INIT_2C (256'h{INIT_2C}),
.INIT_2D (256'h{INIT_2D}),
.INIT_2E (256'h{INIT_2E}),
.INIT_2F (256'h{INIT_2F}),
.INIT_30 (256'h{INIT_30}),
.INIT_31 (256'h{INIT_31}),
.INIT_32 (256'h{INIT_32}),
.INIT_33 (256'h{INIT_33}),
.INIT_34 (256'h{INIT_34}),
.INIT_35 (256'h{INIT_35}),
.INIT_36 (256'h{INIT_36}),
.INIT_37 (256'h{INIT_37}),
.INIT_38 (256'h{INIT_38}),
.INIT_39 (256'h{INIT_39}),
.INIT_3A (256'h{INIT_3A}),
.INIT_3B (256'h{INIT_3B}),
.INIT_3C (256'h{INIT_3C}),
.INIT_3D (256'h{INIT_3D}),
.INIT_3E (256'h{INIT_3E}),
.INIT_3F (256'h{INIT_3F}),
.INIT_40 (256'h{INIT_40}),
.INIT_41 (256'h{INIT_41}),
.INIT_42 (256'h{INIT_42}),
.INIT_43 (256'h{INIT_43}),
.INIT_44 (256'h{INIT_44}),
.INIT_45 (256'h{INIT_45}),
.INIT_46 (256'h{INIT_46}),
.INIT_47 (256'h{INIT_47}),
.INIT_48 (256'h{INIT_48}),
.INIT_49 (256'h{INIT_49}),
.INIT_4A (256'h{INIT_4A}),
.INIT_4B (256'h{INIT_4B}),
.INIT_4C (256'h{INIT_4C}),
.INIT_4D (256'h{INIT_4D}),
.INIT_4E (256'h{INIT_4E}),
.INIT_4F (256'h{INIT_4F}),
.INIT_50 (256'h{INIT_50}),
.INIT_51 (256'h{INIT_51}),
.INIT_52 (256'h{INIT_52}),
.INIT_53 (256'h{INIT_53}),
.INIT_54 (256'h{INIT_54}),
.INIT_55 (256'h{INIT_55}),
.INIT_56 (256'h{INIT_56}),
.INIT_57 (256'h{INIT_57}),
.INIT_58 (256'h{INIT_58}),
.INIT_59 (256'h{INIT_59}),
.INIT_5A (256'h{INIT_5A}),
.INIT_5B (256'h{INIT_5B}),
.INIT_5C (256'h{INIT_5C}),
.INIT_5D (256'h{INIT_5D}),
.INIT_5E (256'h{INIT_5E}),
.INIT_5F (256'h{INIT_5F}),
.INIT_60 (256'h{INIT_60}),
.INIT_61 (256'h{INIT_61}),
.INIT_62 (256'h{INIT_62}),
.INIT_63 (256'h{INIT_63}),
.INIT_64 (256'h{INIT_64}),
.INIT_65 (256'h{INIT_65}),
.INIT_66 (256'h{INIT_66}),
.INIT_67 (256'h{INIT_67}),
.INIT_68 (256'h{INIT_68}),
.INIT_69 (256'h{INIT_69}),
.INIT_6A (256'h{INIT_6A}),
.INIT_6B (256'h{INIT_6B}),
.INIT_6C (256'h{INIT_6C}),
.INIT_6D (256'h{INIT_6D}),
.INIT_6E (256'h{INIT_6E}),
.INIT_6F (256'h{INIT_6F}),
.INIT_70 (256'h{INIT_70}),
.INIT_71 (256'h{INIT_71}),
.INIT_72 (256'h{INIT_72}),
.INIT_73 (256'h{INIT_73}),
.INIT_74 (256'h{INIT_74}),
.INIT_75 (256'h{INIT_75}),
.INIT_76 (256'h{INIT_76}),
.INIT_77 (256'h{INIT_77}),
.INIT_78 (256'h{INIT_78}),
.INIT_79 (256'h{INIT_79}),
.INIT_7A (256'h{INIT_7A}),
.INIT_7B (256'h{INIT_7B}),
.INIT_7C (256'h{INIT_7C}),
.INIT_7D (256'h{INIT_7D}),
.INIT_7E (256'h{INIT_7E}),
.INIT_7F (256'h{INIT_7F}),
.INITP_00 (256'h{INITP_00}),
.INITP_01 (256'h{INITP_01}),
.INITP_02 (256'h{INITP_02}),
.INITP_03 (256'h{INITP_03}),
.INITP_04 (256'h{INITP_04}),
.INITP_05 (256'h{INITP_05}),
.INITP_06 (256'h{INITP_06}),
.INITP_07 (256'h{INITP_07}),
.INITP_08 (256'h{INITP_08}),
.INITP_09 (256'h{INITP_09}),
.INITP_0A (256'h{INITP_0A}),
.INITP_0B (256'h{INITP_0B}),
.INITP_0C (256'h{INITP_0C}),
.INITP_0D (256'h{INITP_0D}),
.INITP_0E (256'h{INITP_0E}),
.INITP_0F (256'h{INITP_0F}))
kcpsm6_rom( .ADDRARDADDR (address_a),
.ENARDEN (enable),
.CLKARDCLK (clk),
.DOADO (data_out_a[31:0]),
.DOPADOP (data_out_a[35:32]),
.DIADI (data_in_a[31:0]),
.DIPADIP (data_in_a[35:32]),
.WEA (4'h0),
.REGCEAREGCE (1'b0),
.RSTRAMARSTRAM (1'b0),
.RSTREGARSTREG (1'b0),
.ADDRBWRADDR (address_b),
.ENBWREN (enable_b),
.CLKBWRCLK (clk_b),
.DOBDO (data_out_b[31:0]),
.DOPBDOP (data_out_b[35:32]),
.DIBDI (data_in_b[31:0]),
.DIPBDIP (data_in_b[35:32]),
.WEBWE (we_b),
.REGCEB (1'b0),
.RSTRAMB (1'b0),
.RSTREGB (1'b0),
.CASCADEINA (1'b0),
.CASCADEINB (1'b0),
.CASCADEOUTA (),
.CASCADEOUTB (),
.DBITERR (),
.ECCPARITY (),
.RDADDRECC (),
.SBITERR (),
.INJECTDBITERR (1'b0),
.INJECTSBITERR (1'b0));
//
//
endmodule
//
////////////////////////////////////////////////////////////////////////////////////
//
// END OF FILE {name}.v
//
////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,557 @@
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2010-2013, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
ROM_form.v
Production template for a 4K program for KCPSM6 in a 7-Series device using
2 x RAMB36E1 primitives.
Nick Sawyer (Xilinx Ltd)
Ken Chapman (Xilinx Ltd)
5th August 2011 - First Release
14th March 2013 - Unused address inputs on BRAMs connected High to reflect
descriptions UG473.
This is a verilog template file for the KCPSM6 assembler.
This verilog file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.v' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the verilog.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2010-2013, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
//
// Production definition of a 4K program for KCPSM6 in a 7-Series device using
// 2 x RAMB36E1 primitives.
//
//
// Program defined by '{psmname}.psm'.
//
// Generated by KCPSM6 Assembler: {timestamp}.
//
// Assembler used ROM_form template: ROM_form_7S_4K_14March13.v
//
//
module {name} (
input [11:0] address,
output [17:0] instruction,
input enable,
input clk);
//
//
wire [15:0] address_a;
wire [35:0] data_in_a;
wire [35:0] data_out_a_l;
wire [35:0] data_out_a_h;
wire [15:0] address_b;
wire [35:0] data_in_b_l;
wire [35:0] data_out_b_l;
wire [35:0] data_in_b_h;
wire [35:0] data_out_b_h;
wire enable_b;
wire clk_b;
wire [7:0] we_b;
//
//
assign address_a = {1'b1, address[11:0], 3'b111};
assign instruction = {data_out_a_h[32], data_out_a_h[7:0], data_out_a_l[32], data_out_a_l[7:0]};
assign data_in_a = 36'b000000000000000000000000000000000000;
//
assign address_b = 16'b1111111111111111;
assign data_in_b_l = {3'h0, data_out_b_l[32], 24'b000000000000000000000000, data_out_b_l[7:0]};
assign data_in_b_h = {3'h0, data_out_b_h[32], 24'b000000000000000000000000, data_out_b_h[7:0]};
assign enable_b = 1'b0;
assign we_b = 8'h00;
assign clk_b = 1'b0;
//
RAMB36E1 # ( .READ_WIDTH_A (9),
.WRITE_WIDTH_A (9),
.DOA_REG (0),
.INIT_A (36'h000000000),
.RSTREG_PRIORITY_A ("REGCE"),
.SRVAL_A (36'h000000000),
.WRITE_MODE_A ("WRITE_FIRST"),
.READ_WIDTH_B (9),
.WRITE_WIDTH_B (9),
.DOB_REG (0),
.INIT_B (36'h000000000),
.RSTREG_PRIORITY_B ("REGCE"),
.SRVAL_B (36'h000000000),
.WRITE_MODE_B ("WRITE_FIRST"),
.INIT_FILE ("NONE"),
.SIM_COLLISION_CHECK ("ALL"),
.RAM_MODE ("TDP"),
.RDADDR_COLLISION_HWCONFIG ("DELAYED_WRITE"),
.EN_ECC_READ ("FALSE"),
.EN_ECC_WRITE ("FALSE"),
.RAM_EXTENSION_A ("NONE"),
.RAM_EXTENSION_B ("NONE"),
.SIM_DEVICE ("7SERIES"),
.INIT_00 (256'h{[8:0]_INIT_00}),
.INIT_01 (256'h{[8:0]_INIT_01}),
.INIT_02 (256'h{[8:0]_INIT_02}),
.INIT_03 (256'h{[8:0]_INIT_03}),
.INIT_04 (256'h{[8:0]_INIT_04}),
.INIT_05 (256'h{[8:0]_INIT_05}),
.INIT_06 (256'h{[8:0]_INIT_06}),
.INIT_07 (256'h{[8:0]_INIT_07}),
.INIT_08 (256'h{[8:0]_INIT_08}),
.INIT_09 (256'h{[8:0]_INIT_09}),
.INIT_0A (256'h{[8:0]_INIT_0A}),
.INIT_0B (256'h{[8:0]_INIT_0B}),
.INIT_0C (256'h{[8:0]_INIT_0C}),
.INIT_0D (256'h{[8:0]_INIT_0D}),
.INIT_0E (256'h{[8:0]_INIT_0E}),
.INIT_0F (256'h{[8:0]_INIT_0F}),
.INIT_10 (256'h{[8:0]_INIT_10}),
.INIT_11 (256'h{[8:0]_INIT_11}),
.INIT_12 (256'h{[8:0]_INIT_12}),
.INIT_13 (256'h{[8:0]_INIT_13}),
.INIT_14 (256'h{[8:0]_INIT_14}),
.INIT_15 (256'h{[8:0]_INIT_15}),
.INIT_16 (256'h{[8:0]_INIT_16}),
.INIT_17 (256'h{[8:0]_INIT_17}),
.INIT_18 (256'h{[8:0]_INIT_18}),
.INIT_19 (256'h{[8:0]_INIT_19}),
.INIT_1A (256'h{[8:0]_INIT_1A}),
.INIT_1B (256'h{[8:0]_INIT_1B}),
.INIT_1C (256'h{[8:0]_INIT_1C}),
.INIT_1D (256'h{[8:0]_INIT_1D}),
.INIT_1E (256'h{[8:0]_INIT_1E}),
.INIT_1F (256'h{[8:0]_INIT_1F}),
.INIT_20 (256'h{[8:0]_INIT_20}),
.INIT_21 (256'h{[8:0]_INIT_21}),
.INIT_22 (256'h{[8:0]_INIT_22}),
.INIT_23 (256'h{[8:0]_INIT_23}),
.INIT_24 (256'h{[8:0]_INIT_24}),
.INIT_25 (256'h{[8:0]_INIT_25}),
.INIT_26 (256'h{[8:0]_INIT_26}),
.INIT_27 (256'h{[8:0]_INIT_27}),
.INIT_28 (256'h{[8:0]_INIT_28}),
.INIT_29 (256'h{[8:0]_INIT_29}),
.INIT_2A (256'h{[8:0]_INIT_2A}),
.INIT_2B (256'h{[8:0]_INIT_2B}),
.INIT_2C (256'h{[8:0]_INIT_2C}),
.INIT_2D (256'h{[8:0]_INIT_2D}),
.INIT_2E (256'h{[8:0]_INIT_2E}),
.INIT_2F (256'h{[8:0]_INIT_2F}),
.INIT_30 (256'h{[8:0]_INIT_30}),
.INIT_31 (256'h{[8:0]_INIT_31}),
.INIT_32 (256'h{[8:0]_INIT_32}),
.INIT_33 (256'h{[8:0]_INIT_33}),
.INIT_34 (256'h{[8:0]_INIT_34}),
.INIT_35 (256'h{[8:0]_INIT_35}),
.INIT_36 (256'h{[8:0]_INIT_36}),
.INIT_37 (256'h{[8:0]_INIT_37}),
.INIT_38 (256'h{[8:0]_INIT_38}),
.INIT_39 (256'h{[8:0]_INIT_39}),
.INIT_3A (256'h{[8:0]_INIT_3A}),
.INIT_3B (256'h{[8:0]_INIT_3B}),
.INIT_3C (256'h{[8:0]_INIT_3C}),
.INIT_3D (256'h{[8:0]_INIT_3D}),
.INIT_3E (256'h{[8:0]_INIT_3E}),
.INIT_3F (256'h{[8:0]_INIT_3F}),
.INIT_40 (256'h{[8:0]_INIT_40}),
.INIT_41 (256'h{[8:0]_INIT_41}),
.INIT_42 (256'h{[8:0]_INIT_42}),
.INIT_43 (256'h{[8:0]_INIT_43}),
.INIT_44 (256'h{[8:0]_INIT_44}),
.INIT_45 (256'h{[8:0]_INIT_45}),
.INIT_46 (256'h{[8:0]_INIT_46}),
.INIT_47 (256'h{[8:0]_INIT_47}),
.INIT_48 (256'h{[8:0]_INIT_48}),
.INIT_49 (256'h{[8:0]_INIT_49}),
.INIT_4A (256'h{[8:0]_INIT_4A}),
.INIT_4B (256'h{[8:0]_INIT_4B}),
.INIT_4C (256'h{[8:0]_INIT_4C}),
.INIT_4D (256'h{[8:0]_INIT_4D}),
.INIT_4E (256'h{[8:0]_INIT_4E}),
.INIT_4F (256'h{[8:0]_INIT_4F}),
.INIT_50 (256'h{[8:0]_INIT_50}),
.INIT_51 (256'h{[8:0]_INIT_51}),
.INIT_52 (256'h{[8:0]_INIT_52}),
.INIT_53 (256'h{[8:0]_INIT_53}),
.INIT_54 (256'h{[8:0]_INIT_54}),
.INIT_55 (256'h{[8:0]_INIT_55}),
.INIT_56 (256'h{[8:0]_INIT_56}),
.INIT_57 (256'h{[8:0]_INIT_57}),
.INIT_58 (256'h{[8:0]_INIT_58}),
.INIT_59 (256'h{[8:0]_INIT_59}),
.INIT_5A (256'h{[8:0]_INIT_5A}),
.INIT_5B (256'h{[8:0]_INIT_5B}),
.INIT_5C (256'h{[8:0]_INIT_5C}),
.INIT_5D (256'h{[8:0]_INIT_5D}),
.INIT_5E (256'h{[8:0]_INIT_5E}),
.INIT_5F (256'h{[8:0]_INIT_5F}),
.INIT_60 (256'h{[8:0]_INIT_60}),
.INIT_61 (256'h{[8:0]_INIT_61}),
.INIT_62 (256'h{[8:0]_INIT_62}),
.INIT_63 (256'h{[8:0]_INIT_63}),
.INIT_64 (256'h{[8:0]_INIT_64}),
.INIT_65 (256'h{[8:0]_INIT_65}),
.INIT_66 (256'h{[8:0]_INIT_66}),
.INIT_67 (256'h{[8:0]_INIT_67}),
.INIT_68 (256'h{[8:0]_INIT_68}),
.INIT_69 (256'h{[8:0]_INIT_69}),
.INIT_6A (256'h{[8:0]_INIT_6A}),
.INIT_6B (256'h{[8:0]_INIT_6B}),
.INIT_6C (256'h{[8:0]_INIT_6C}),
.INIT_6D (256'h{[8:0]_INIT_6D}),
.INIT_6E (256'h{[8:0]_INIT_6E}),
.INIT_6F (256'h{[8:0]_INIT_6F}),
.INIT_70 (256'h{[8:0]_INIT_70}),
.INIT_71 (256'h{[8:0]_INIT_71}),
.INIT_72 (256'h{[8:0]_INIT_72}),
.INIT_73 (256'h{[8:0]_INIT_73}),
.INIT_74 (256'h{[8:0]_INIT_74}),
.INIT_75 (256'h{[8:0]_INIT_75}),
.INIT_76 (256'h{[8:0]_INIT_76}),
.INIT_77 (256'h{[8:0]_INIT_77}),
.INIT_78 (256'h{[8:0]_INIT_78}),
.INIT_79 (256'h{[8:0]_INIT_79}),
.INIT_7A (256'h{[8:0]_INIT_7A}),
.INIT_7B (256'h{[8:0]_INIT_7B}),
.INIT_7C (256'h{[8:0]_INIT_7C}),
.INIT_7D (256'h{[8:0]_INIT_7D}),
.INIT_7E (256'h{[8:0]_INIT_7E}),
.INIT_7F (256'h{[8:0]_INIT_7F}),
.INITP_00 (256'h{[8:0]_INITP_00}),
.INITP_01 (256'h{[8:0]_INITP_01}),
.INITP_02 (256'h{[8:0]_INITP_02}),
.INITP_03 (256'h{[8:0]_INITP_03}),
.INITP_04 (256'h{[8:0]_INITP_04}),
.INITP_05 (256'h{[8:0]_INITP_05}),
.INITP_06 (256'h{[8:0]_INITP_06}),
.INITP_07 (256'h{[8:0]_INITP_07}),
.INITP_08 (256'h{[8:0]_INITP_08}),
.INITP_09 (256'h{[8:0]_INITP_09}),
.INITP_0A (256'h{[8:0]_INITP_0A}),
.INITP_0B (256'h{[8:0]_INITP_0B}),
.INITP_0C (256'h{[8:0]_INITP_0C}),
.INITP_0D (256'h{[8:0]_INITP_0D}),
.INITP_0E (256'h{[8:0]_INITP_0E}),
.INITP_0F (256'h{[8:0]_INITP_0F}))
kcpsm6_rom_l(.ADDRARDADDR (address_a),
.ENARDEN (enable),
.CLKARDCLK (clk),
.DOADO (data_out_a_l[31:0]),
.DOPADOP (data_out_a_l[35:32]),
.DIADI (data_in_a[31:0]),
.DIPADIP (data_in_a[35:32]),
.WEA (4'h0),
.REGCEAREGCE (1'b0),
.RSTRAMARSTRAM (1'b0),
.RSTREGARSTREG (1'b0),
.ADDRBWRADDR (address_b),
.ENBWREN (enable_b),
.CLKBWRCLK (clk_b),
.DOBDO (data_out_b_l[31:0]),
.DOPBDOP (data_out_b_l[35:32]),
.DIBDI (data_in_b_l[31:0]),
.DIPBDIP (data_in_b_l[35:32]),
.WEBWE (we_b),
.REGCEB (1'b0),
.RSTRAMB (1'b0),
.RSTREGB (1'b0),
.CASCADEINA (1'b0),
.CASCADEINB (1'b0),
.CASCADEOUTA (),
.CASCADEOUTB (),
.DBITERR (),
.ECCPARITY (),
.RDADDRECC (),
.SBITERR (),
.INJECTDBITERR (1'b0),
.INJECTSBITERR (1'b0));
//
RAMB36E1 # ( .READ_WIDTH_A (9),
.WRITE_WIDTH_A (9),
.DOA_REG (0),
.INIT_A (36'h000000000),
.RSTREG_PRIORITY_A ("REGCE"),
.SRVAL_A (36'h000000000),
.WRITE_MODE_A ("WRITE_FIRST"),
.READ_WIDTH_B (9),
.WRITE_WIDTH_B (9),
.DOB_REG (0),
.INIT_B (36'h000000000),
.RSTREG_PRIORITY_B ("REGCE"),
.SRVAL_B (36'h000000000),
.WRITE_MODE_B ("WRITE_FIRST"),
.INIT_FILE ("NONE"),
.SIM_COLLISION_CHECK ("ALL"),
.RAM_MODE ("TDP"),
.RDADDR_COLLISION_HWCONFIG ("DELAYED_WRITE"),
.EN_ECC_READ ("FALSE"),
.EN_ECC_WRITE ("FALSE"),
.RAM_EXTENSION_A ("NONE"),
.RAM_EXTENSION_B ("NONE"),
.SIM_DEVICE ("7SERIES"),
.INIT_00 (256'h{[17:9]_INIT_00}),
.INIT_01 (256'h{[17:9]_INIT_01}),
.INIT_02 (256'h{[17:9]_INIT_02}),
.INIT_03 (256'h{[17:9]_INIT_03}),
.INIT_04 (256'h{[17:9]_INIT_04}),
.INIT_05 (256'h{[17:9]_INIT_05}),
.INIT_06 (256'h{[17:9]_INIT_06}),
.INIT_07 (256'h{[17:9]_INIT_07}),
.INIT_08 (256'h{[17:9]_INIT_08}),
.INIT_09 (256'h{[17:9]_INIT_09}),
.INIT_0A (256'h{[17:9]_INIT_0A}),
.INIT_0B (256'h{[17:9]_INIT_0B}),
.INIT_0C (256'h{[17:9]_INIT_0C}),
.INIT_0D (256'h{[17:9]_INIT_0D}),
.INIT_0E (256'h{[17:9]_INIT_0E}),
.INIT_0F (256'h{[17:9]_INIT_0F}),
.INIT_10 (256'h{[17:9]_INIT_10}),
.INIT_11 (256'h{[17:9]_INIT_11}),
.INIT_12 (256'h{[17:9]_INIT_12}),
.INIT_13 (256'h{[17:9]_INIT_13}),
.INIT_14 (256'h{[17:9]_INIT_14}),
.INIT_15 (256'h{[17:9]_INIT_15}),
.INIT_16 (256'h{[17:9]_INIT_16}),
.INIT_17 (256'h{[17:9]_INIT_17}),
.INIT_18 (256'h{[17:9]_INIT_18}),
.INIT_19 (256'h{[17:9]_INIT_19}),
.INIT_1A (256'h{[17:9]_INIT_1A}),
.INIT_1B (256'h{[17:9]_INIT_1B}),
.INIT_1C (256'h{[17:9]_INIT_1C}),
.INIT_1D (256'h{[17:9]_INIT_1D}),
.INIT_1E (256'h{[17:9]_INIT_1E}),
.INIT_1F (256'h{[17:9]_INIT_1F}),
.INIT_20 (256'h{[17:9]_INIT_20}),
.INIT_21 (256'h{[17:9]_INIT_21}),
.INIT_22 (256'h{[17:9]_INIT_22}),
.INIT_23 (256'h{[17:9]_INIT_23}),
.INIT_24 (256'h{[17:9]_INIT_24}),
.INIT_25 (256'h{[17:9]_INIT_25}),
.INIT_26 (256'h{[17:9]_INIT_26}),
.INIT_27 (256'h{[17:9]_INIT_27}),
.INIT_28 (256'h{[17:9]_INIT_28}),
.INIT_29 (256'h{[17:9]_INIT_29}),
.INIT_2A (256'h{[17:9]_INIT_2A}),
.INIT_2B (256'h{[17:9]_INIT_2B}),
.INIT_2C (256'h{[17:9]_INIT_2C}),
.INIT_2D (256'h{[17:9]_INIT_2D}),
.INIT_2E (256'h{[17:9]_INIT_2E}),
.INIT_2F (256'h{[17:9]_INIT_2F}),
.INIT_30 (256'h{[17:9]_INIT_30}),
.INIT_31 (256'h{[17:9]_INIT_31}),
.INIT_32 (256'h{[17:9]_INIT_32}),
.INIT_33 (256'h{[17:9]_INIT_33}),
.INIT_34 (256'h{[17:9]_INIT_34}),
.INIT_35 (256'h{[17:9]_INIT_35}),
.INIT_36 (256'h{[17:9]_INIT_36}),
.INIT_37 (256'h{[17:9]_INIT_37}),
.INIT_38 (256'h{[17:9]_INIT_38}),
.INIT_39 (256'h{[17:9]_INIT_39}),
.INIT_3A (256'h{[17:9]_INIT_3A}),
.INIT_3B (256'h{[17:9]_INIT_3B}),
.INIT_3C (256'h{[17:9]_INIT_3C}),
.INIT_3D (256'h{[17:9]_INIT_3D}),
.INIT_3E (256'h{[17:9]_INIT_3E}),
.INIT_3F (256'h{[17:9]_INIT_3F}),
.INIT_40 (256'h{[17:9]_INIT_40}),
.INIT_41 (256'h{[17:9]_INIT_41}),
.INIT_42 (256'h{[17:9]_INIT_42}),
.INIT_43 (256'h{[17:9]_INIT_43}),
.INIT_44 (256'h{[17:9]_INIT_44}),
.INIT_45 (256'h{[17:9]_INIT_45}),
.INIT_46 (256'h{[17:9]_INIT_46}),
.INIT_47 (256'h{[17:9]_INIT_47}),
.INIT_48 (256'h{[17:9]_INIT_48}),
.INIT_49 (256'h{[17:9]_INIT_49}),
.INIT_4A (256'h{[17:9]_INIT_4A}),
.INIT_4B (256'h{[17:9]_INIT_4B}),
.INIT_4C (256'h{[17:9]_INIT_4C}),
.INIT_4D (256'h{[17:9]_INIT_4D}),
.INIT_4E (256'h{[17:9]_INIT_4E}),
.INIT_4F (256'h{[17:9]_INIT_4F}),
.INIT_50 (256'h{[17:9]_INIT_50}),
.INIT_51 (256'h{[17:9]_INIT_51}),
.INIT_52 (256'h{[17:9]_INIT_52}),
.INIT_53 (256'h{[17:9]_INIT_53}),
.INIT_54 (256'h{[17:9]_INIT_54}),
.INIT_55 (256'h{[17:9]_INIT_55}),
.INIT_56 (256'h{[17:9]_INIT_56}),
.INIT_57 (256'h{[17:9]_INIT_57}),
.INIT_58 (256'h{[17:9]_INIT_58}),
.INIT_59 (256'h{[17:9]_INIT_59}),
.INIT_5A (256'h{[17:9]_INIT_5A}),
.INIT_5B (256'h{[17:9]_INIT_5B}),
.INIT_5C (256'h{[17:9]_INIT_5C}),
.INIT_5D (256'h{[17:9]_INIT_5D}),
.INIT_5E (256'h{[17:9]_INIT_5E}),
.INIT_5F (256'h{[17:9]_INIT_5F}),
.INIT_60 (256'h{[17:9]_INIT_60}),
.INIT_61 (256'h{[17:9]_INIT_61}),
.INIT_62 (256'h{[17:9]_INIT_62}),
.INIT_63 (256'h{[17:9]_INIT_63}),
.INIT_64 (256'h{[17:9]_INIT_64}),
.INIT_65 (256'h{[17:9]_INIT_65}),
.INIT_66 (256'h{[17:9]_INIT_66}),
.INIT_67 (256'h{[17:9]_INIT_67}),
.INIT_68 (256'h{[17:9]_INIT_68}),
.INIT_69 (256'h{[17:9]_INIT_69}),
.INIT_6A (256'h{[17:9]_INIT_6A}),
.INIT_6B (256'h{[17:9]_INIT_6B}),
.INIT_6C (256'h{[17:9]_INIT_6C}),
.INIT_6D (256'h{[17:9]_INIT_6D}),
.INIT_6E (256'h{[17:9]_INIT_6E}),
.INIT_6F (256'h{[17:9]_INIT_6F}),
.INIT_70 (256'h{[17:9]_INIT_70}),
.INIT_71 (256'h{[17:9]_INIT_71}),
.INIT_72 (256'h{[17:9]_INIT_72}),
.INIT_73 (256'h{[17:9]_INIT_73}),
.INIT_74 (256'h{[17:9]_INIT_74}),
.INIT_75 (256'h{[17:9]_INIT_75}),
.INIT_76 (256'h{[17:9]_INIT_76}),
.INIT_77 (256'h{[17:9]_INIT_77}),
.INIT_78 (256'h{[17:9]_INIT_78}),
.INIT_79 (256'h{[17:9]_INIT_79}),
.INIT_7A (256'h{[17:9]_INIT_7A}),
.INIT_7B (256'h{[17:9]_INIT_7B}),
.INIT_7C (256'h{[17:9]_INIT_7C}),
.INIT_7D (256'h{[17:9]_INIT_7D}),
.INIT_7E (256'h{[17:9]_INIT_7E}),
.INIT_7F (256'h{[17:9]_INIT_7F}),
.INITP_00 (256'h{[17:9]_INITP_00}),
.INITP_01 (256'h{[17:9]_INITP_01}),
.INITP_02 (256'h{[17:9]_INITP_02}),
.INITP_03 (256'h{[17:9]_INITP_03}),
.INITP_04 (256'h{[17:9]_INITP_04}),
.INITP_05 (256'h{[17:9]_INITP_05}),
.INITP_06 (256'h{[17:9]_INITP_06}),
.INITP_07 (256'h{[17:9]_INITP_07}),
.INITP_08 (256'h{[17:9]_INITP_08}),
.INITP_09 (256'h{[17:9]_INITP_09}),
.INITP_0A (256'h{[17:9]_INITP_0A}),
.INITP_0B (256'h{[17:9]_INITP_0B}),
.INITP_0C (256'h{[17:9]_INITP_0C}),
.INITP_0D (256'h{[17:9]_INITP_0D}),
.INITP_0E (256'h{[17:9]_INITP_0E}),
.INITP_0F (256'h{[17:9]_INITP_0F}))
kcpsm6_rom_h(.ADDRARDADDR (address_a),
.ENARDEN (enable),
.CLKARDCLK (clk),
.DOADO (data_out_a_h[31:0]),
.DOPADOP (data_out_a_h[35:32]),
.DIADI (data_in_a[31:0]),
.DIPADIP (data_in_a[35:32]),
.WEA (4'h0),
.REGCEAREGCE (1'b0),
.RSTRAMARSTRAM (1'b0),
.RSTREGARSTREG (1'b0),
.ADDRBWRADDR (address_b),
.ENBWREN (enable_b),
.CLKBWRCLK (clk_b),
.DOBDO (data_out_b_h[31:0]),
.DOPBDOP (data_out_b_h[35:32]),
.DIBDI (data_in_b_h[31:0]),
.DIPBDIP (data_in_b_h[35:32]),
.WEBWE (we_b),
.REGCEB (1'b0),
.RSTRAMB (1'b0),
.RSTREGB (1'b0),
.CASCADEINA (1'b0),
.CASCADEINB (1'b0),
.CASCADEOUTA (),
.CASCADEOUTB (),
.DBITERR (),
.ECCPARITY (),
.RDADDRECC (),
.SBITERR (),
.INJECTDBITERR (1'b0),
.INJECTSBITERR (1'b0));
//
endmodule
//
////////////////////////////////////////////////////////////////////////////////////
//
// END OF FILE {name}.v
//
////////////////////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,266 @@
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2010-2011, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
ROM_form.v
Production template for a 1K program for KCPSM6 in a Spartan-6 device using a
RAMB18WER primitive.
Nick Sawyer (Xilinx Ltd)
Ken Chapman (Xilinx Ltd)
5th August 2011
This is a verilog template file for the KCPSM6 assembler.
This verilog file is not valid as input directly into a synthesis or a simulation tool.
The assembler will read this template and insert the information required to complete
the definition of program ROM and write it out to a new '.v' file that is ready for
synthesis and simulation.
This template can be modified to define alternative memory definitions. However, you are
responsible for ensuring the template is correct as the assembler does not perform any
checking of the verilog.
The assembler identifies all text enclosed by {} characters, and replaces these
character strings. All templates should include these {} character strings for
the assembler to work correctly.
The next line is used to determine where the template actually starts.
{begin template}
//
///////////////////////////////////////////////////////////////////////////////////////////
// Copyright <EFBFBD> 2010-2011, Xilinx, Inc.
// This file contains confidential and proprietary information of Xilinx, Inc. and is
// protected under U.S. and international copyright and other intellectual property laws.
///////////////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to
// you by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE
// MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY
// DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
// OR FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable
// (whether in contract or tort, including negligence, or under any other theory
// of liability) for any loss or damage of any kind or nature related to, arising
// under or in connection with these materials, including for any direct, or any
// indirect, special, incidental, or consequential loss or damage (including loss
// of data, profits, goodwill, or any type of loss or damage suffered as a result
// of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-safe, or for use in any
// application requiring fail-safe performance, such as life-support or safety
// devices or systems, Class III medical devices, nuclear facilities, applications
// related to the deployment of airbags, or any other applications that could lead
// to death, personal injury, or severe property or environmental damage
// (individually and collectively, "Critical Applications"). Customer assumes the
// sole risk and liability of any use of Xilinx products in Critical Applications,
// subject only to applicable laws and regulations governing limitations on product
// liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
///////////////////////////////////////////////////////////////////////////////////////////
//
//
// Production definition of a 1K program for KCPSM6 in a Spartan-6 device using a
// RAMB18WER primitive.
//
// Note: The complete 12-bit address bus is connected to KCPSM6 to facilitate future code
// expansion with minimum changes being required to the hardware description.
// Only the lower 10-bits of the address are actually used for the 1K address range
// 000 to 3FF hex.
//
// Program defined by '{psmname}.psm'.
//
// Generated by KCPSM6 Assembler: {timestamp}.
//
//
module {name} (
input [11:0] address,
output [17:0] instruction,
input enable,
input clk);
//
//
wire [13:0] address_a;
wire [35:0] data_in_a;
wire [35:0] data_out_a;
wire [35:0] data_out_b;
wire [13:0] address_b;
wire [35:0] data_in_b;
wire enable_b;
wire clk_b;
wire [3:0] we_b;
//
assign address_a = {address[9:0], 4'b0000};
assign instruction = {data_out_a[33:32], data_out_a[15:0]};
assign data_in_a = {34'b0000000000000000000000000000000000, address[11:10]};
//
assign address_b = 14'b00000000000000;
assign data_in_b = {2'h0, data_out_b[33:32], 16'b0000000000000000, data_out_b[15:0]};
assign enable_b = 1'b0;
assign we_b = 4'h0;
assign clk_b = 1'b0;
//
//
//
RAMB16BWER # ( .DATA_WIDTH_A (18),
.DOA_REG (0),
.EN_RSTRAM_A ("FALSE"),
.INIT_A (32'h000000000),
.RST_PRIORITY_A ("CE"),
.SRVAL_A (32'h000000000),
.WRITE_MODE_A ("WRITE_FIRST"),
.DATA_WIDTH_B (18),
.DOB_REG (0),
.EN_RSTRAM_B ("FALSE"),
.INIT_B (32'h000000000),
.RST_PRIORITY_B ("CE"),
.SRVAL_B (32'h000000000),
.WRITE_MODE_B ("WRITE_FIRST"),
.RSTTYPE ("SYNC"),
.INIT_FILE ("NONE"),
.SIM_COLLISION_CHECK ("ALL"),
.SIM_DEVICE ("SPARTAN6"),
.INIT_00 (256'h{INIT_00}),
.INIT_01 (256'h{INIT_01}),
.INIT_02 (256'h{INIT_02}),
.INIT_03 (256'h{INIT_03}),
.INIT_04 (256'h{INIT_04}),
.INIT_05 (256'h{INIT_05}),
.INIT_06 (256'h{INIT_06}),
.INIT_07 (256'h{INIT_07}),
.INIT_08 (256'h{INIT_08}),
.INIT_09 (256'h{INIT_09}),
.INIT_0A (256'h{INIT_0A}),
.INIT_0B (256'h{INIT_0B}),
.INIT_0C (256'h{INIT_0C}),
.INIT_0D (256'h{INIT_0D}),
.INIT_0E (256'h{INIT_0E}),
.INIT_0F (256'h{INIT_0F}),
.INIT_10 (256'h{INIT_10}),
.INIT_11 (256'h{INIT_11}),
.INIT_12 (256'h{INIT_12}),
.INIT_13 (256'h{INIT_13}),
.INIT_14 (256'h{INIT_14}),
.INIT_15 (256'h{INIT_15}),
.INIT_16 (256'h{INIT_16}),
.INIT_17 (256'h{INIT_17}),
.INIT_18 (256'h{INIT_18}),
.INIT_19 (256'h{INIT_19}),
.INIT_1A (256'h{INIT_1A}),
.INIT_1B (256'h{INIT_1B}),
.INIT_1C (256'h{INIT_1C}),
.INIT_1D (256'h{INIT_1D}),
.INIT_1E (256'h{INIT_1E}),
.INIT_1F (256'h{INIT_1F}),
.INIT_20 (256'h{INIT_20}),
.INIT_21 (256'h{INIT_21}),
.INIT_22 (256'h{INIT_22}),
.INIT_23 (256'h{INIT_23}),
.INIT_24 (256'h{INIT_24}),
.INIT_25 (256'h{INIT_25}),
.INIT_26 (256'h{INIT_26}),
.INIT_27 (256'h{INIT_27}),
.INIT_28 (256'h{INIT_28}),
.INIT_29 (256'h{INIT_29}),
.INIT_2A (256'h{INIT_2A}),
.INIT_2B (256'h{INIT_2B}),
.INIT_2C (256'h{INIT_2C}),
.INIT_2D (256'h{INIT_2D}),
.INIT_2E (256'h{INIT_2E}),
.INIT_2F (256'h{INIT_2F}),
.INIT_30 (256'h{INIT_30}),
.INIT_31 (256'h{INIT_31}),
.INIT_32 (256'h{INIT_32}),
.INIT_33 (256'h{INIT_33}),
.INIT_34 (256'h{INIT_34}),
.INIT_35 (256'h{INIT_35}),
.INIT_36 (256'h{INIT_36}),
.INIT_37 (256'h{INIT_37}),
.INIT_38 (256'h{INIT_38}),
.INIT_39 (256'h{INIT_39}),
.INIT_3A (256'h{INIT_3A}),
.INIT_3B (256'h{INIT_3B}),
.INIT_3C (256'h{INIT_3C}),
.INIT_3D (256'h{INIT_3D}),
.INIT_3E (256'h{INIT_3E}),
.INIT_3F (256'h{INIT_3F}),
.INITP_00 (256'h{INITP_00}),
.INITP_01 (256'h{INITP_01}),
.INITP_02 (256'h{INITP_02}),
.INITP_03 (256'h{INITP_03}),
.INITP_04 (256'h{INITP_04}),
.INITP_05 (256'h{INITP_05}),
.INITP_06 (256'h{INITP_06}),
.INITP_07 (256'h{INITP_07}))
kcpsm6_rom( .ADDRA (address_a),
.ENA (enable),
.CLKA (clk),
.DOA (data_out_a[31:0]),
.DOPA (data_out_a[35:32]),
.DIA (data_in_a[31:0]),
.DIPA (data_in_a[35:32]),
.WEA (4'h0),
.REGCEA (1'b0),
.RSTA (1'b0),
.ADDRB (address_b),
.ENB (enable_b),
.CLKB (clk_b),
.DOB (data_out_b[31:0]),
.DOPB (data_out_b[35:32]),
.DIB (data_in_b[31:0]),
.DIPB (data_in_b[35:32]),
.WEB (we_b),
.REGCEB (1'b0),
.RSTB (1'b0));
//
//
endmodule
//
////////////////////////////////////////////////////////////////////////////////////
//
// END OF FILE {name}.v
//
////////////////////////////////////////////////////////////////////////////////////

Some files were not shown because too many files have changed in this diff Show More