Commit 4afd6871 authored by Tristan Gingold's avatar Tristan Gingold

Remove obsolete documents.

parent c8c252f8
----------------------------------------
-- vme64x_core review
----------------------------------------
-- Severity:
-- (!) - serious
-- (m) - medium
-- (_) - cosmetic
-- (o) - optimization
-- (?) - question
----------------------------------------
-- I've gone sequentially reading the files,
-- so probably some of the details written
-- here are already solved within the cores.
----------------------------------------
Project in repo:
-- (o) Repo could be restructured. There are references (such as some schematics
and reference pdfs quite outdated) that should be replaced/removed. Take
a look to /trunk/documentation/references.
General:
-- (_) Use Vim/Emacs for better alignment.
-- (_) Comment the Doxygen way and remove unnecesary "End of file" comments?
-- (_) Add name to processes.
--------------------
vm64_pack.vhd
--------------------
-- (m) Reference the "AM table" (line 75) to a document. It could be probably
added the HEX CODEs from the VME6$ reference manual as comments.
-- (o) Probably c_FUNC[X]_ADER_[Y] constants can be all replaced by a
function call. Less error prone.
-- (_) t_transferType error could be renamed to something different: TT_Error.
-- (o) I would put a prefix at the begining of every state of the fsm. For instance,
in t_mainFSMstates (line 303 on):
IDLE -> S0_IDLE
DECODE_ACCESS -> S1_DECODE_ACCESS
WAIT_FOR_DS -> S2_WAIT_FOR_DS
Besides, I would put a reset state, R0_RESET, to ease the task of
resetting the core (probably already done in IDLE).
-- (o) Same as above for t_initState (line 344).
-- (_) Indenting (Vim is '=' key over a visual block) ;-)
-- (_) Hidden characters (return line in DOS systems) in some parts of the
code (line 689 i.e.)
-- (_) Use consistent initialization of output signal, either inside the
component or outside. See FlipFlopD and EdgeDetection.
-- (_) I prefer having all the inputs and outputs in different lines while
declarating a component.
-- (_) Notation: start with lower cases. See FlipFlopD, EdgeDetection,
RisEdgeDetection.
-- (_) Notation: some input signals have missed the _i prefix.
--------------------
--------------------
vme_CR_pack.vhd
--------------------
-- (_) Probably better to put slv's in VHDL'93 hexadecimal style
(c_amcap, c_amcap0,...).
Notation: c_[HIGERCASES]. Add a reference note to where are the values gotten from.
--------------------
--------------------
vme_CSR_pack.vhd
--------------------
--------------------
--------------------
VME64xCore_Top.vhd
--------------------
-- (?) If all the operations are controlled by DS lines (and others), is it necessary
to place double or triple buffering in the address and data lines?
In any case, which is the signal that triggers the FSM? In case there are two,
probably it will be good placed a window wait time to overcome the problems
you had while decoding operation to perform.
-- (_) Probably better to move the process to freeze the data received from the
wishbone operation (line 531) inside VME_Wb_master.vhd
--------------------
--------------------
VME_Wb_master.vhd
--------------------
-- (_) Added suffixes _i, _o to the ports.
-- (_) Probably mainFSMreset can drive the 'reset' port directly.
"One reset to rule them all".
In case of if then structures with a little of combinatorial, instead of:
if reset = '1' or mainFSMreset = '1' or (stall_i = '0' and s_cyc = '1') then
I prefer:
if (reset = '1')
or (mainFSMreset = '1')
or (stall_i = '0' and s_cyc = '1') then
think, it is easier to read.
--------------------
--------------------
VME_CR_CSR_Space.vhd
--------------------
-- (_) In processes in which one of the signals to be updated is updated in much
less situations than the rest of signals, I try to put it in a different
process to have all the cases correctly covered.
Maybe s_bar_written and reset_flag in p_CSR_Write can get independency.
--------------------
--------------------
VME_CRAM.vhd
--------------------
-- (_) Change (clk'event and clk = '1') for rising_edge(clk)
--------------------
--------------------
VME_bus.vhd
--------------------
-- (o) Remove "use IEEE.numeric_std.unsigned;", redundant.
-- (o) Maybe better to have a common global reset. Processes for s_wberr1, s_rty1.
-- (?) Debug leds should be removed?
-- (?) VME_RST_n_i what for?
--------------------
--------------------
VME_SharedComps.vhd
--------------------
-- (_) Hidden characters.
--------------------
--------------------
VME_Init.vhd
--------------------
-- (o) As Tom said, it is probably better group FUNC into an array. Then add some
translation functions in one of the packages, it will help to reduce errors
and being a little less verbose in the components.
-- (o) I would put a general reset control process to keep coherence in the reset
of the module.
--------------------
--------------------
VME_IRQ_Controller.vhd
--------------------
-- (_) In the process in line 317, it would be better have records that
which are assigned with predefined record constants. It will reduce the
length and possible errors while assigning values to the outputs.
-- (o) In the same process the when others => clause is missing. Probably it
would be better set a deferred output before the case, so it will always
set an output (no latches here??).
-- (o) Coming back to the process in line 243, the previous comment is applicable.
Recommend to preassign before the case to avoid unwanted latches.
-- (o) Reset as Tom pointed out. Keep consistent notation to avoid this kind of
problems.
--------------------
--------------------
VME_swapper.vhd
--------------------
--------------------
--------------------
VME_Func_Math.vhd
--------------------
-- (_) The ports can be reduced if reagrouped. Use of translation function to
keep STD_LOGIC_VECTOR boundaries easy to work with.
--------------------
--------------------
VME_Am_Match.vhd
--------------------
--------------------
--------------------
VME_Access_Decode.vhd
--------------------
--------------------
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="for_loop.svg"
inkscape:export-filename="/opt/ohwr/vme64x_core/hdl/vme64x-core/rtl/CodeReview_2Nov2012/for_loop.png"
inkscape:export-xdpi="180"
inkscape:export-ydpi="180">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="327.68922"
inkscape:cy="933.57312"
inkscape:document-units="px"
inkscape:current-layer="g3992"
showgrid="false"
inkscape:window-width="1366"
inkscape:window-height="691"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g3036"
transform="translate(53.571429,42.225289)">
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3005"
d="m 68.690373,49.028166 0,68.437834"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3007"
d="m 68.824303,49.36999 21.71828,18.687823"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:transform-center-y="-15.267857"
inkscape:transform-center-x="-10.535714"
inkscape:connector-curvature="0"
id="path3007-3"
d="M 90.546643,98.524 68.82836,117.08555"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3027"
d="m 90.471788,67.715987 0.06313,31.248417"
style="fill:none;stroke:#000000;stroke-width:1.00812888px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
transform="translate(98.42184,42.225289)"
id="g3036-2">
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3005-6"
d="m 68.690373,49.028166 0,68.437834"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3007-4"
d="m 68.824303,49.36999 21.71828,18.687823"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:transform-center-y="-15.267857"
inkscape:transform-center-x="-10.535714"
inkscape:connector-curvature="0"
id="path3007-3-1"
d="M 90.546643,98.524 68.82836,117.08555"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3027-2"
d="m 90.471788,67.715987 0.06313,31.248417"
style="fill:none;stroke:#000000;stroke-width:1.00812888px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
transform="translate(143.27226,42.225289)"
id="g3036-6">
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3005-8"
d="m 68.690373,49.028166 0,68.437834"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3007-9"
d="m 68.824303,49.36999 21.71828,18.687823"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:transform-center-y="-15.267857"
inkscape:transform-center-x="-10.535714"
inkscape:connector-curvature="0"
id="path3007-3-0"
d="M 90.546643,98.524 68.82836,117.08555"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3027-6"
d="m 90.471788,67.715987 0.06313,31.248417"
style="fill:none;stroke:#000000;stroke-width:1.00812888px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
transform="translate(188.12266,42.225289)"
id="g3036-26">
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3005-5"
d="m 68.690373,49.028166 0,68.437834"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3007-2"
d="m 68.824303,49.36999 21.71828,18.687823"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:transform-center-y="-15.267857"
inkscape:transform-center-x="-10.535714"
inkscape:connector-curvature="0"
id="path3007-3-6"
d="M 90.546643,98.524 68.82836,117.08555"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3027-5"
d="m 90.471788,67.715987 0.06313,31.248417"
style="fill:none;stroke:#000000;stroke-width:1.00812888px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
transform="translate(232.9731,42.225289)"
id="g3036-0">
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3005-4"
d="m 68.690373,49.028166 0,68.437834"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3007-8"
d="m 68.824303,49.36999 21.71828,18.687823"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:transform-center-y="-15.267857"
inkscape:transform-center-x="-10.535714"
inkscape:connector-curvature="0"
id="path3007-3-7"
d="M 90.546643,98.524 68.82836,117.08555"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3027-0"
d="m 90.471788,67.715987 0.06313,31.248417"
style="fill:none;stroke:#000000;stroke-width:1.00812888px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
transform="translate(277.82351,42.225289)"
id="g3036-7">
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3005-9"
d="m 68.690373,49.028166 0,68.437834"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3007-39"
d="m 68.824303,49.36999 21.71828,18.687823"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:transform-center-y="-15.267857"
inkscape:transform-center-x="-10.535714"
inkscape:connector-curvature="0"
id="path3007-3-2"
d="M 90.546643,98.524 68.82836,117.08555"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3027-8"
d="m 90.471788,67.715987 0.06313,31.248417"
style="fill:none;stroke:#000000;stroke-width:1.00812888px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
transform="translate(322.67392,42.225289)"
id="g3036-78">
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3005-91"
d="m 68.690373,49.028166 0,68.437834"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3007-5"
d="m 68.824303,49.36999 21.71828,18.687823"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:transform-center-y="-15.267857"
inkscape:transform-center-x="-10.535714"
inkscape:connector-curvature="0"
id="path3007-3-4"
d="M 90.546643,98.524 68.82836,117.08555"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3027-9"
d="m 90.471788,67.715987 0.06313,31.248417"
style="fill:none;stroke:#000000;stroke-width:1.00812888px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
transform="translate(367.52435,42.225289)"
id="g3036-70">
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3005-81"
d="m 68.690373,49.028166 0,68.437834"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3007-99"
d="m 68.824303,49.36999 21.71828,18.687823"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:transform-center-y="-15.267857"
inkscape:transform-center-x="-10.535714"
inkscape:connector-curvature="0"
id="path3007-3-78"
d="M 90.546643,98.524 68.82836,117.08555"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3027-25"
d="m 90.471788,67.715987 0.06313,31.248417"
style="fill:none;stroke:#000000;stroke-width:1.00812888px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
id="g3992">
<path
inkscape:connector-curvature="0"
id="path3930"
d="m 109.61086,107.45402 12.71057,0"
style="fill:none;stroke:#000000;stroke-width:0.75460809px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3930-2"
d="m 155.03432,107.45402 11.66211,0"
style="fill:none;stroke:#000000;stroke-width:0.72281569px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:transform-center-y="0.5"
inkscape:transform-center-x="-2.0616501"
inkscape:connector-curvature="0"
id="path3930-0"
d="m 202.73969,107.36473 8.77817,0.0893"
style="fill:none;stroke:#000000;stroke-width:0.75977755px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
sodipodi:nodetypes="cc" />
<path
inkscape:connector-curvature="0"
id="path3930-5"
d="m 249.71866,107.45402 7.15634,0"
style="fill:none;stroke:#000000;stroke-width:0.56621891px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3930-4"
d="m 293.54228,107.36473 7.97558,0.0893"
style="fill:none;stroke:#000000;stroke-width:0.76505297px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
sodipodi:nodetypes="cc" />
<path
inkscape:connector-curvature="0"
id="path3930-9"
d="m 339.00003,107.45402 7.33926,0"
style="fill:none;stroke:#000000;stroke-width:0.57340956px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3930-6"
d="m 382.79828,107.45402 8.71958,0"
style="fill:none;stroke:#000000;stroke-width:0.62500966px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3930-21"
d="m 430.12778,107.45402 5.85436,0"
style="fill:none;stroke:#000000;stroke-width:0.51212823px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 293.9732,107.40683 0.0893,-22.321442 -41.25,0 -6.69643,-0.08928"
id="path4325-6-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 339.33035,107.49611 0.0893,-22.321437 -41.25,0 -6.69643,-0.08928"
id="path4325-6-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 383.25891,107.5854 0.0893,-22.321441 -41.25,0 -6.69643,-0.08928"
id="path4325-6-24"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 430.31249,107.67468 0.0893,-22.321436 -41.25,0 -6.69643,-0.08928"
id="path4325-6-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<g
id="g3512"
transform="translate(305.06607,186.87822)">
<path
sodipodi:nodetypes="cssscc"
inkscape:connector-curvature="0"
id="path4393"
d="m 78.050366,39.930217 c 0,0 4.266184,0.2065 7.628653,-1.55442 2.544415,-1.33251 4.257867,-4.66042 4.162282,-7.4098 -0.08027,-2.30879 -1.64967,-5.44707 -3.945034,-6.80248 -3.679364,-2.17266 -7.958768,-2.03812 -7.958768,-2.03812 z"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4395"
d="M 43.690385,36.27499 74.78958,36.40126"
style="fill:none;stroke:#000000;stroke-width:0.95157194px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4395-0"
d="m 43.815366,25.98406 34.345187,0.12627"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<text
sodipodi:linespacing="125%"
id="text4415"
y="23.143007"
x="14.394673"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-size:8px"
y="23.143007"
x="14.394673"
id="tspan4417"
sodipodi:role="line">ModuleEnable</tspan></text>
<text
sodipodi:linespacing="125%"
id="text4415-0"
y="44.467262"
x="14.093782"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-size:8px"
y="44.467262"
x="14.093782"
id="tspan4417-8"
sodipodi:role="line">InitInProgress</tspan></text>
<path
transform="matrix(0.91026714,0,0,1,12.262227,-19.884564)"
d="m 72.321427,56.201466 c 0,0.739667 -0.799491,1.339285 -1.785714,1.339285 -0.986223,0 -1.785714,-0.599618 -1.785714,-1.339285 0,-0.739667 0.799491,-1.339286 1.785714,-1.339286 0.986223,0 1.785714,0.599619 1.785714,1.339286 z"
sodipodi:ry="1.3392857"
sodipodi:rx="1.7857143"
sodipodi:cy="56.201466"
sodipodi:cx="70.535713"
id="path4440"
style="opacity:0.9;fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="arc" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:1.00942969px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 130.18341,59.286224 0.12627,39.113147"
id="path4613"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.00732076px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 175.3246,59.761036 0.12627,38.949883"
id="path4613-6"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.00414348px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 220.27639,60.326162 0.12627,38.704554"
id="path4613-7"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.01467645px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 265.48072,60.013574 0.12627,39.520795"
id="path4613-8"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.01409078px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 310.68505,60.013574 0.12627,39.475197"
id="path4613-0"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.01624918px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 355.63683,60.266112 0.12627,39.643411"
id="path4613-1"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.02190983px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 400.58862,60.013574 0.12627,40.086276"
id="path4613-3"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.01409078px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 445.66668,60.139844 0.12627,39.475191"
id="path4613-82"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="110.48543"
y="55.846695"
id="text4737"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4739"
x="110.48543"
y="55.846695"
style="font-size:6px">s_func_sel(0)</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="158.55989"
y="56.534592"
id="text4737-7"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4739-9"
x="158.55989"
y="56.534592"
style="font-size:6px">s_func_sel(1)</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="203.25916"
y="56.787125"
id="text4737-4"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4739-1"
x="203.25916"
y="56.787125"
style="font-size:6px">s_func_sel(2)</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="248.96855"
y="56.534588"
id="text4737-1"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4739-18"
x="248.96855"
y="56.534588"
style="font-size:6px">s_func_sel(3)</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="293.41528"
y="56.408318"
id="text4737-43"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4739-8"
x="293.41528"
y="56.408318"
style="font-size:6px">s_func_sel(4)</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="337.23062"
y="56.155781"
id="text4737-0"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4739-6"
x="337.23062"
y="56.155781"
style="font-size:6px">s_func_sel(5)</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="382.1824"
y="56.155781"
id="text4737-8"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4739-80"
x="382.1824"
y="56.155781"
style="font-size:6px">s_func_sel(6)</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="429.78586"
y="56.408321"
id="text4737-86"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4739-3"
x="429.78586"
y="56.408321"
style="font-size:6px">s_func_sel(7)</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="549.01794"
y="122.01169"
id="text4816"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4818"
x="549.01794"
y="122.01169">CardSel</tspan></text>
<rect
style="opacity:0.90000000000000002;fill:none;stroke:#000000;stroke-width:1.4;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect4820"
width="65.154839"
height="81.317284"
x="479.31738"
y="112.92032" />
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="481.84277"
y="130.09293"
id="text4840"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4842"
x="481.84277"
y="130.09293">D</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="531.34027"
y="128.57768"
id="text4844"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4846"
x="531.34027"
y="128.57768">Q</tspan></text>
<g
id="g3522"
transform="matrix(0,-1,-1,0,673.30616,666.34192)">
<path
inkscape:connector-curvature="0"
id="path4848"
d="m 504.06612,193.73252 5.05076,-7.07107 5.55584,7.57614"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4850"
d="m 509.11688,210.90511 0.0631,-16.79329"
style="fill:none;stroke:#000000;stroke-width:0.89972264px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="461.17645"
y="155.40222"
id="text4852"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4854"
x="461.17645"
y="155.40222"
style="font-size:8px">clk</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 394.91072,217.89789 113.30357,0.17858 0.0893,-23.83929"
id="path3526"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="505.40179"
y="192.54076"
id="text3528"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3530"
x="505.40179"
y="192.54076"
style="font-size:10px">R</tspan></text>
</g>
<g
transform="translate(0.4590705,35.265795)"
id="g3992-7">
<path
inkscape:connector-curvature="0"
id="path3930-213"
d="m 109.61086,107.45402 12.71057,0"
style="fill:none;stroke:#000000;stroke-width:0.75460809px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3930-2-4"
d="m 153.95252,107.38706 12.74391,0.067"
style="fill:none;stroke:#000000;stroke-width:0.72281569px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
sodipodi:nodetypes="cc" />
<path
inkscape:transform-center-y="0.5"
inkscape:transform-center-x="-2.0616501"
inkscape:connector-curvature="0"
id="path3930-0-9"
d="m 198.63255,107.45402 12.88531,0"
style="fill:none;stroke:#000000;stroke-width:0.75977755px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3930-5-4"
d="m 242.94123,107.45402 13.93377,0"
style="fill:none;stroke:#000000;stroke-width:0.79008406px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3930-4-1"
d="m 288.45299,107.45402 13.06487,0"
style="fill:none;stroke:#000000;stroke-width:0.76505297px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3930-9-9"
d="m 333.09833,107.45402 13.24096,0"
style="fill:none;stroke:#000000;stroke-width:0.77019137px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3930-6-5"
d="m 378.28306,107.45402 13.2348,0"
style="fill:none;stroke:#000000;stroke-width:0.77001226px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3930-21-7"
d="m 424.49477,107.45402 11.48737,0"
style="fill:none;stroke:#000000;stroke-width:0.71737999px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.8;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 144.07301,122.64303 10.73287,0.12627 -1e-5,19.95051"
id="path4044"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 188.77226,122.7693 10.73287,0.12627 -1e-5,19.95051"
id="path4044-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 233.59778,122.89558 10.16466,0.1894 -1e-5,19.95051"
id="path4044-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 278.54956,122.89557 10.73287,0.12627 -10e-6,19.95051"
id="path4044-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 323.24882,122.70617 10.73287,0.12627 -1e-5,19.95051"
id="path4044-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 368.45314,123.02184 10.73287,0.12627 -1e-5,19.95051"
id="path4044-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 413.1524,122.95871 12.12183,0.12627 -10e-6,19.95051"
id="path4044-16"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 457.67857,125.21932 478.75,125.39789"
id="path4106"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="100.0051"
y="147.2655"
id="text4108"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4110"
x="100.0051"
y="147.2655">0</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="100.10059"
y="111.82933"
id="text4108-3"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4110-1"
x="100.10059"
y="111.82933">1</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="124.47032"
y="111.07854"
id="text4108-3-4"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4110-1-2"
x="124.47032"
y="111.07854"
style="font-size:8px">1</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="124.53771"
y="145.38329"
id="text4108-3-4-0"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4110-1-2-2"
x="124.53771"
y="145.38329"
style="font-size:8px">0</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="168.80415"
y="145.50566"
id="text4108-3-4-0-2"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4110-1-2-2-8"
x="168.80415"
y="145.50566"
style="font-size:8px">0</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="213.62968"
y="145.25311"
id="text4108-3-4-0-8"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4110-1-2-2-1"
x="213.62968"
y="145.25311"
style="font-size:8px">0</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="259.2128"
y="146.13699"
id="text4108-3-4-0-6"
sodipodi:linespacing="125%"
inkscape:transform-center-x="-4.0406102"><tspan
sodipodi:role="line"
id="tspan4110-1-2-2-3"
x="259.2128"
y="146.13699"
style="font-size:8px">0</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="304.16461"
y="146.13699"
id="text4108-3-4-0-9"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4110-1-2-2-83"
x="304.16461"
y="146.13699"
style="font-size:8px">0</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="348.86383"
y="146.26326"
id="text4108-3-4-0-7"
sodipodi:linespacing="125%"
inkscape:transform-center-x="-3.783392"
inkscape:transform-center-y="1.0101525"><tspan
sodipodi:role="line"
id="tspan4110-1-2-2-4"
x="348.86383"
y="146.26326"
style="font-size:8px">0</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="393.56308"
y="146.13699"
id="text4108-3-4-0-23"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4110-1-2-2-86"
x="393.56308"
y="146.13699"
style="font-size:8px">0</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="438.38861"
y="146.89461"
id="text4108-3-4-0-4"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4110-1-2-2-7"
x="438.38861"
y="146.89461"
style="font-size:8px">0</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="437.37848"
y="110.90793"
id="text4108-3-4-0-43"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4110-1-2-2-0"
x="437.37848"
y="110.90793"
style="font-size:8px">1</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="393.74338"
y="111.16438"
id="text4108-3-4-0-43-9"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4110-1-2-2-0-1"
x="393.74338"
y="111.16438"
style="font-size:8px">1</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="348.03397"
y="111.0381"
id="text4108-3-4-0-43-5"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4110-1-2-2-0-5"
x="348.03397"
y="111.0381"
style="font-size:8px">1</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="302.82965"
y="111.16438"
id="text4108-3-4-0-43-1"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4110-1-2-2-0-7"
x="302.82965"
y="111.16438"
style="font-size:8px">1</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="258.63547"
y="110.78558"
id="text4108-3-4-0-43-17"
sodipodi:linespacing="125%"
inkscape:transform-center-x="-3.9143411"
inkscape:transform-center-y="0.75761441"><tspan
sodipodi:role="line"
id="tspan4110-1-2-2-0-13"
x="258.63547"
y="110.78558"
style="font-size:8px">1</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="213.1786"
y="110.53303"
id="text4108-3-4-0-43-4"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4110-1-2-2-0-12"
x="213.1786"
y="110.53303"
style="font-size:8px">1</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="168.22682"
y="110.91183"
id="text4108-3-4-0-43-3"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4110-1-2-2-0-8"
x="168.22682"
y="110.91183"
style="font-size:8px">1</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 155.17857,107.71933 0,-22.678578 -41.25,-0.357143 0,22.500001"
id="path4325"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 203.125,107.2729 0.0893,-22.321437 -41.25,0 -6.69643,-0.08928"
id="path4325-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 250.31248,107.40682 0.0893,-22.321433 -41.25,0 -6.69643,-0.08928"
id="path4325-6-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 545.04818,125.45794 21.07143,0.17857"
id="path4106-6"
inkscape:connector-curvature="0" />
</g>
</svg>
VME64xCore_Top.vhd
------------------
In the comments, it would be useful to explain a bit about the context
this core expects in the PCB, e.g. what chips are used in the SVEC
board (which is the reference platform for this core). This would help
people understand e.g. how open collector outputs are dealt with, or
what the VME_LWORD_n_o and VME_ADDR_o outputs are for.
VME_AS_n_i and VME_DS_n_i are passed to two different synchronizer
blocks in parallel. The actual implementation of this will depend on
how clever the synthesis tool is. If it is not clever, it will not
notice it can tap the three-FF synchronizer to get the double-FF
output, and we will have two parallel synchronizers: not good,
especially considering that one of them will not use the I/O FFs. If
these double-clocked signals are really needed, the triple-clocking
block could deliver an extra ouput port for them.
There are a number of outputs which are supposed to go to the outside
world (VME_DTACK_n_o, WE_o, VME_DATA_DIR_o...) and which are not using
I/O FFs because they are the result of some combinational logic. This
will result in tricky timing issues, and need complex constraints to
P&R to guarantee consistent results. I would strongly advise to make
sure all these signals are outputs of I/O FFs, with any necessary
logic placed *before* these FFs. In general, all inputs to the core
should be sampled before using them, and all outputs should be the
result of clocking in I/O FFs.
VME_bus.vhd
-----------
There is a comment at line 527 saying:
-- If the S_FPGA will be provided to a core who drives these lines
-- without
-- erase the A_FPGA the above mentioned lines should be changed to 'Z'
-- !!!
This should probably change to become a generic so that people can
decide on the behaviour they want. It will then be more visible, not
hidden in the middle of the code. The sentence itself it quite
cryptic. This core should not assume it is used in a board with a
S_FPGA and a A_FPGA.
VME_IRQ_Controller.vhd
----------------------
Text diagram in the initial comments not clear regarding state
IACKOUT2.
Line 69: "To avoid the time constraint" -> "To respect the timing
constraint"
Signal naming is not consistent. If the "s_" prefix is used, it should
be used for all internal signals.
Line 104: "reset" is clearly used as an active-low signal in this
entity, and it is an input port, so its name should be "reset_n_i".
Instantiation of many FlipFlopD components: a single clocked process
would be more compact and easier to understand.
Line 247: why should the interrupt controller not be allowed to go to
the IRQ state when VME_IACKIN_n_i='0'?
Line 256: once we have allowed going to the IRQ state even if
VME_IACKIN_n_i is low, we should detect a falling edge of
VME_IACKIN_n_i while in the IRQ state to proceed. A simple detection
of '0' won't work anymore.
Line 321: In the IDLE state this block should drive whatever it gets
from IACKIN into IACKOUT. Otherwise it is blocking interrupt
acknowledgement for any cards to the right of the module where it is
instantiated. In general the IACKIN-IACKOUT daisy-chain needs to be
looked at in detail. Driving IACKOUT with AS as is done in other
states looks weird. IACKOUT should be driven by IACKIN when the IACK
chain is not intercepted by this block.
Line 445: these are active-low signals so their value after reset
should be '1', not '0'.
I don't understand the whole DS_LATCH thing. We detect in state
WAIT_DS that there was some change in the DS lines. This makes us go
to state LATCH_DS, where the DS lines are latched. Then we check if
VME_DS_latched(0) is '0' in the ACK_INT state. Wouldn't it be simpler
to just wait for DS(0) to become '0'?
Line 467: s_enable opens the sampling gate for INT_Req only when
either we have not latched a request (with INT_Req_sample) or when
DTACK is being driven low. In this last case, we are in the DTACK
state (until AS goes up) and any INT_Req pulse will go through the
sampling but in a transient way, i.e. it will not "stick" and we will
lose it. This behavior should be documented so that users of the core
know.
Synthesis warnings:
------------------------------------------------------------------------------------------------------------------------------------------------------------------
/vme64x_pack.vhd" Line 805: Function f_div8 does not always return a value.
/VME_CR_CSR_Space.vhd" Line 223: Case choice must be a locally static expression
/VME_CR_CSR_Space.vhd" Line 227: Case choice must be a locally static expression
/VME_CR_CSR_Space.vhd" Line 232: Case choice must be a locally static expression
/VME_CR_CSR_Space.vhd" Line 246: Case choice must be a locally static expression
/VME_CR_CSR_Space.vhd" Line 253: Case choice must be a locally static expression
/VME_CR_CSR_Space.vhd" Line 256: Case choice must be a locally static expression
/VME_CR_CSR_Space.vhd" Line 263: Case choice must be a locally static expression
/VME_CR_CSR_Space.vhd" Line 267: Case choice must be a locally static expression
/VME_CR_CSR_Space.vhd" Line 270: Case choice must be a locally static expression
/VME_CR_CSR_Space.vhd" Line 273: Case choice must be a locally static expression
/VME_bus.vhd" Line 506: Assignment to s_2elatchaddr ignored, since the identifier is never used
/VME_bus.vhd" Line 508: Assignment to s_berr ignored, since the identifier is never used
/VME_bus.vhd" Line 1344: Assignment to s_cyclecount ignored, since the identifier is never used
/VME_Funct_Match.vhd" Line 213: Assignment to debugfunct ignored, since the identifier is never used
/VME_Am_Match.vhd" Line 124: Assignment to debugam ignored, since the identifier is never used
/VME_bus.vhd" Line 188: Net <s_phase1addr[63]> does not have a driver.
/VME_bus.vhd" Line 189: Net <s_phase2addr[7]> does not have a driver.
/VME_bus.vhd" Line 204: Net <s_XAM[7]> does not have a driver.
/VME_CR_CSR_Space.vhd" Line 191: Assignment to s_barerror ignored, since the identifier is never used
/VME_bus.vhd" line 1726. All outputs of instance <DS1EdgeDetect> of block <EdgeDetection> are unconnected in block <VME_bus>. Underlying logic will be removed.
/VME_bus.vhd" line 1492: Output port <Funct_Sel> of the instance <Inst_Access_Decode> is unconnected or connected to loadless signal.
/VME_bus.vhd" line 1726: Output port <sigEdge_o> of the instance <DS1EdgeDetect> is unconnected or connected to loadless signal.
Signal <s_phase1addr<63:8>> is used but never assigned. This sourceless signal will be automatically connected to value GND.
Signal <s_phase2addr<7:0>> is used but never assigned. This sourceless signal will be automatically connected to value GND.
Signal <s_XAM> is used but never assigned. This sourceless signal will be automatically connected to value GND.
INFO:Xst:2261 - The FF/Latch <DSinputSample/reg_1_0> in Unit <VME64xCore_Top> is equivalent to the following FF/Latch, which will be removed : <DSinputSample1/reg_1_0>
INFO:Xst:2261 - The FF/Latch <DSinputSample/reg_1_1> in Unit <VME64xCore_Top> is equivalent to the following FF/Latch, which will be removed : <DSinputSample1/reg_1_1>
INFO:Xst:2261 - The FF/Latch <Inst_VME_bus/ASrisingEdge/s_1> in Unit <VME64xCore_Top> is equivalent to the following FF/Latch, which will be removed : <Inst_VME_bus/ASfallingEdge/s_1>
INFO:Xst:2261 - The FF/Latch <ASinputSample/s_1> in Unit <VME64xCore_Top> is equivalent to the following FF/Latch, which will be removed : <ASinputSample1/s_1>
General comments:
------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Add a reset output port on core's top level.
This reset should come from the software reset bit in CSR.
* Update the Manifest file.
-> Remove VME_DpBlockRam.vhd
-> Add VME_CRAM.vhd
* Change MBLT endian register name to SWAP configuration register (or something similar).
* Move to a git repository.
----------------------------------------
-- vme64x_core review
----------------------------------------
-- Severity:
-- (!) - serious
-- (m) - medium
-- (_) - cosmetic
-- (o) - optimization
-- (?) - question
vme64x_user_manual
(_) There is some random use of capital letters throughout the document.
vme_bus.vhd
(m) It was pointed out in the presentation that the DS toggle could eventually not be properlly detected. In the datasheet it is stated that the skew between this lines can be up to a maximum of 20ns. A single wait state may be not enough if the vme core is clocked at 100MHz. On the other hand it is not necessary if the core is clocked at f<50Mhz. Probably it could be a good idea to use some generic (as carlos sugested) to insert/remove wait states depending on the clocking frequency.
VME_IRQ_Controller.vhd
(m!) As it is already pointed out by Javier the IACKIN-IACKOUT should be looked in more detail. I doubt the interrupt handler can deal correctly with rule 4.41 (30ns min skew between AS release and IACKOUT release). Notice that this rule applies on the VME connector edge so even with an internal latency of 2 cycles at 10ns you still have all the propagations delays to take care of.
\documentclass[a4paper,11pt]{article}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[italian,UKenglish]{babel}
%\usepackage[english]{babel}
\usepackage{graphicx}
\begin{document}
\begin{titlepage}
\begin{center}
\huge{\textbf{vme64x-core review 1}}\\
\end{center}
\vspace{17cm}
\begin{flushleft}
Author: Davide Pedretti
\end{flushleft}
\vspace{1cm}
\begin{flushright}
Date: 12/11/2012
\end{flushright}
\end{titlepage}
\newpage
\begin{center}
\LARGE{\textbf{Carlos}}
\end{center}
\begin{itemize}
\item \textit{(m) Reference the AM table (line 75) to a document...}\\
Done. Hex code added as comments.
\item \textit{(?)If all the operations are controlled by DS lines (and others),
is it necessary to place double or triple buffering in the address and data
lines?} \\
Good observation: It is possible place triple buffering only in the control
lines: VME\_GA\_i, VME\_AS\_n\_i, VME\_WRITE\_n\_i, VME\_DS\_n\_i, VME\_RST\_n\_i, VME\_IACK\_n\_i, VME\_IACKIN\_n\_i.\\
Indeed when the vme64x core latches the address and data lines, they should be stable according with the VME specification.
\item \textit{(o) Remove use IEEE.numeric\_std.unsigned; redundant}\\
Done.
\item \textit{(?) VME\_RST\_n\_i what for?}\\
The Power Monitor Module (A20 MEN in our case) should drive this line.
See page 200 VMEbus specification ANSI/IEEE STD1024-1987.
\item \textit{(?) Debug leds should be removed?}\\
Yes. The leds were used during the debug.
\item \textit{(o) In the same process the when others => clause is missing.
Probably it would be better set a deferred output before the case,
so it will always set an output}\\
Assigned a default configuration before the case.\\
Added when others =>.
\item \textit{(o) Coming back to the process in line 243, the previous comment
is applicable. Recommend to preassign before the case to avoid unwanted latches
}.\\
Assigned a default configuration before the case.\\
Added when others =>.
\item \textit{(\_) In the process in line 317, it would be better have records that
which are assigned with predefined record constants. It will reduce the
length and possible errors while assigning values to the outputs}.\\
Done.
\end{itemize}
\newpage
\begin{center}
\LARGE{\textbf{Javier}}
\end{center}
\begin{itemize}
\item VME\_bus.vhd\\
\textit{
There is a comment at line 527 saying:
-- If the S\_FPGA will be provided to a core who drives these lines
-- without
-- erase the A\_FPGA the above mentioned lines should be changed to 'Z'
-- !!!
This should probably change to become a generic so that people can
decide on the behaviour they want. It will then be more visible, not
hidden in the middle of the code. The sentence itself it quite
cryptic. This core should not assume it is used in a board with a
S\_FPGA and a A\_FPGA.}
The comment is related to the SVEC board, so it has been removed from the middle
of the code and
it has been moved on the general description at the beginning of the file.\\
Each VME board plugged in a slot acts as a VME salve module and it has only one
CR/CSR space (conforming with the specification) so only one FPGA at time
must drive the output lines on the VME bus; only one FPGA at time can carry the
vme64x core.\\
In other words, only one FPGA at a time shall answer to the software.\\
\item \textit{VME\_IRQ\_Controller.vhd}
\begin{itemize}
\item \textit{Text diagram in the initial comments not clear regarding state
IACKOUT2}\\
Added comment: \\
If the slave module does not have an interrupt pending (IDLE state) and it
receives a falling edge on the IACKIN, it shall pass the falling edge through the
daisy chain. To obtain this the IACKOUT2 state has been added.
\item \textit{To avoid the time constraint" -> "To respect the timing
constraint}\\
Corrected
\item \textit{Signal naming is not consistent. If the "s\_" prefix is used, it
should be used for all internal signals.}\\
Done. The prefix s\_ is used for all internal signals.
\item \textit{Line 104: "reset" is clearly used as an active-low signal in this
entity, and it is an input port, so its name should be "reset\_n\_i".}\\
Done. reset => reset\_n\_i.
\item \textit{Instantiation of many FlipFlopD components: a single clocked
process would be more compact and easier to understand.}\\
FlipFlopD components replaced by a single clocked process.
\item \textit{Line 247: why should the interrupt controller not be allowed to
go to the IRQ state when VME\_IACKIN\_n\_i='0'?}\\
If VME\_IACKIN\_n\_i='0' and the finite state machine is still in IDLE it means
that we do not have interrupt request pending and this is not the responding
Interrupter and so it passes the falling edge on the IACKOUT on the daisy chain.
As soon as the IACKIN has been released the finite state machine come back to the
IDLE state and it is allowed to go in the IRQ state and request service to the
software.
\item \textit{Line 256: once we have allowed going to the IRQ state even if
VME\_IACKIN\_n\_i is low, we should detect a falling edge of
VME\_IACKIN\_n\_i while in the IRQ state to proceed. A simple detection
of '0' won't work anymore}\\
We go the IRQ state only if VME\_IACKIN\_n\_i is '1'. Once we have allowed
going to the IRQ state we wait until the VME\_IACKIN\_n\_i signal is '0'.
When it is '0' it means that the Interrupt Acknowledge Cycle is in progress and
the finite state machine go in the WAIT\_AS state. At this point we do not need
anymore the detection of '0' on the VME\_IACKIN\_n\_i signal.
I hope I have answered the question.
\item \textit{Line 321: In the IDLE state this block should drive whatever it
gets from IACKIN into IACKOUT. Otherwise it is blocking interrupt
acknowledgement for any cards to the right of the module where it is
instantiated}\\
Indeed when in IDLE, if the VME\_IACKIN\_n\_i is '0' the finite state machine
goes in the IACKOUT2 state where it drives the VME\_IACKOUT\_n\_o.\\
\textit{Driving IACKOUT with AS as is done in other
states looks weird. IACKOUT should be driven by IACKIN when the IACK
chain is not intercepted by this block.}\\
The VMEbus specification tells us that if this is not the responding Interrupter
it shall pass the falling edge of IACKIN* to the next interrupter module in the daisy chain by driving IACKOUT* low.\\
The timing rule 38A (page 183 VMEbus specification) tells us that the Interrupter can take as time it wants before asserting the IACKOUT (because before passing the falling edge the Interrupter has to check if it is the responding Interrupter). Since the timing rule 34 (in the above mentioned page) tells us that the AS* signal is asserted before the IACKIN*, the Interrupter implemented drives the
IACKOUT* with the AS* instead of the IACKIN*. In so doing the Interrupter developed matches the timing rule 35 also at low frequencies.\\ See page 6.
\item \textit{Line 445: these are active-low signals so their value after reset
should be '1', not '0'}.\\
After reset the VME\_IRQ\_n\_o lines are already set to '1'.
\item \textit{I don't understand the whole DS\_LATCH thing. We detect in state
WAIT\_DS that there was some change in the DS lines. This makes us go
to state LATCH\_DS, where the DS lines are latched. Then we check if
VME\_DS\_latched(0) is '0' in the ACK\_INT state. Wouldn't it be simpler
to just wait for DS(0) to become '0'?}\\
In our system the Interrupt Handler supports the data transfer type D08(O) and during the Interrupt Acknowledge Cycle the DS1 line is never asserted (always '1') so it is possible delete the LATCH\_DS state and
delete the further control VME\_DS\_latched(0) = '0' in the ACK\_INT state.
More in general, the type of Interrupter can be also D32. In this case (as shown in the table 31 page 157 VMEbus specification) the Interrupter shall monitor also the DS1* and the LWORD* lines. When I started to implement the Interrupter I did not know in which way the Interrupt Handler was working so I added the LWORD* (never used at the moment) and DS1* lines.
If a D32 interrupter will be used, the finite state machine should be provided with one or more LATCH\_DS states to match the timing rule 13, as done in the VME\_bus component.
The vhdl file has been changed in order to be less confusing. The VME\_DS\_latched(0) = '0' control has been deleted since it was redundant in any case.
\item \textit{Line 467: s\_enable opens the sampling gate for INT\_Req only when
either we have not latched a request (with INT\_Req\_sample) or when
DTACK is being driven low. In this last case, we are in the DTACK
state (until AS goes up) and any INT\_Req pulse will go through the
sampling but in a transient way, i.e. it will not "stick" and we will
lose it. This behavior should be documented so that users of the core
know.}\\
This behavior is undesired. The IRQ\_Controller has been corrected
but in any case interrupt requests coming from the WB application before the Interrupter detects the end of the Interrupt Acknowledge Cycle (AS* rising edge), are lost.
The Interrupter implemented has no queue.
\item \textit{VME\_AS\_n\_i and VME\_DS\_n\_i are passed to two different synchronizer
blocks in parallel. The actual implementation of this will depend on
how clever the synthesis tool is. If it is not clever, it will not
notice it can tap the three-FF synchronizer to get the double-FF
output, and we will have two parallel synchronizers: not good,
especially considering that one of them will not use the I/O FFs. If
these double-clocked signals are really needed, the triple-clocking
block could deliver an extra ouput port for them.}\\
Done.
\end{itemize}
\end{itemize}
\newpage
\begin{center}
\LARGE{\textbf{Pablo}}
\end{center}
\begin{itemize}
\item VME\_IRQ\_Controller.vhd\\
\textit{(m!) As it is already pointed out by Javier the IACKIN-IACKOUT should be looked in more detail. I doubt the interrupt
handler can deal correctly with rule 4.41 (30ns min skew between AS release and IACKOUT release). Notice that this rule applies on the VME connector edge so even with an internal latency of 2 cycles at 10ns you still have all the propagations delays to take care of}\\
Rule 4.41: A partecipating interrupter shall drive IACKOUT* high within this maximum time after the rising edge on AS*.\\
Please note that this rule refers to the interrupter not to the interrupt handler. The figure 55 (page 183 VMEbus specification)
and the related table tell us that the Interrupt Handler does not care the time 35 (so why should we care about that?).\\
However, as you said, if this rule applies on the VME connector edge we are not matching it.
If we drive the IACKOUT* with the IACKIN* as Javier suggested, we do not match this timing rule because of the timing rule 39.
Thus, the only way to always match this rule, regardless of the clock frequency used, is drive the IACKOUT* signal with the AS*
signal not sampled. The metastability will not be a problem in this case because when this signal is outputted it is
already stable.
\item VME\_bus.vhd\\
\textit{(m) It was pointed out in the presentation that the DS toggle could eventually not be properlly detected. In the datasheet it is stated that the skew between this lines can be up to a maximum of 20ns. A single wait state may be not enough if the vme core is clocked at 100MHz. On the other hand it is not necessary if the core is clocked at f<50Mhz. Probably it could be a good idea to use some generic (as carlos sugested) to insert/remove wait states depending on the clocking frequency}\\
Done.\\
Now, in the main finite state machine there are up to 4 LATCH\_DS states selectable with a generic paramiter: g\_clock.
It means that now the timing rule 2.39 page 113 (VMEbus specification ANSI/IEEE STD1014-1987) can be matched up to 200 MHz by
setting the generic g\_clock with the clock period in ns.\\
Adding other LATCH\_DS states the rule 2.39 can be met with frequencies upper to 200 MHz.\\
\begin{itemize}
\item 50 MHz or less: only 1 LATCH\_DS state
\item from 50 MHz to 100 MHz: 2 LATCH\_DS states.
\item from 100 MHz to 150 MHz: 3 LATCH\_DS states.
\item from 150 MHz to 200 MHz: 4 LATCH\_DS states.
\end{itemize}
Please note that in order to meet the timing rule 2.31 (\textit{When using the DTB for two consecutive cycles, the master shall
not drive AS* low until it has been high for this minimum time (30 ns for the slave))} we suggest to use the vme64x core with
frequencies upper than 40 MHz. To match this rule with lower frequencies it is necessary to use different clock domains, and so
a FIFO, inside the vme64x core and sampling the input signals with frequencies upper than 40 MHz.
\end{itemize}
\newpage
\begin{center}
\LARGE{\textbf{Tom}}
\end{center}
\begin{itemize}
\item VME\_bus.vhd\\
\textit{(m) don't comment out code that is not used. Just remove it.}\\
Done
\item VME\_IRQ\_Controller.vhd\\
\textit {(!) line 235: is reset signal active low or high?}\\
As Javier suggested the reset has been renamed reset\_n\_i.
\item VME\_CR\_CSR\_Space.vhd\\
\textit{(m) GADER\_1 loop: please put a single-line comment describing what the generate loop does.}\\
Done.\\
It generates a vector of 8 array (unsigned 32 bits).\\
We need these registers in the decoder.
\item VME\_Access\_Decode.vhd\\
\textit {(o) provide a generic allowing for reduction of device functions. In most cases, we need only 1 A24/A32/D32 BAR.
Decoding and storing BAR configurations takes large percentage of the FPGA resources consumed by the VME core.}\\
I think you can discuss about this point with Julian and David. At the moment I prefer provide the CR/CSR space with all the
functions according with the specification. The aim is to provide you a generic vme64x slave module in agreement with the
specification. You can change the CR/CSR space in order to obtain a custom vme64x slave module at a later time.\\
\textit {(!) process driving cardsel and base\_addr: sequential nonblocking assignments are potentially
dangerous - you are relying on assumption that if any of bits in s\_func\_sel is 1, cardsel (previously set
to 0) will be overwritten by the loop. It's safer to use variables and blocking assignments in such cases.}\\
According to the section 8.7 of the \textit{VHDL for logic synthesis} Third edition, this process is synthesized as shown in the
following figure:\\
\newpage
\begin{figure}[ht]
\begin{center}
\includegraphics[scale=0.70]{for_loop}
\end{center}
\end{figure}
I checked the RTL Schematic after synthesis and, the Base\_Addr and CardSel are synthesized as shown in the above image. \\
I deleted the exit statement that is useless in this case.\\
Thus, the process has not been changed.
\item VME64xCore\_Top.vhd\\
\textit {(\_) Process at lines 530+: I would place it in VME\_bus. This way the top level module will only
act as an interconnect putting together all VME core components.}\\
Done.
The process can be found in the VME\_Wb\_master.vhd component.
\end{itemize}
\newpage
\begin{center}
\LARGE{\textbf{Thedi}}
\end{center}
\begin{itemize}
\item You can find the c\_SIZE constant in the genram\_pkg.\\
\item I developed the code with the Xilinx ISE tool so if you open the code with another editor it may be unaligned.
\item \textit{line 316: this is actually a Moore FSM (outputs depend only on current state)}\\
In the sensitivity list of the project there is also the AS* signal so I wrote: Mealy FSM
\item \textit{I suggest you put the constant values in hex. They are a lot more
readable than binary}.\\
The constant are in binary because each bit corresponds to one AM. These are mask bits.
It is easy to change them in binary.\\
The best thing can be to create a function which takes the AMs as arguments and sets them automatically.
\item \textit{I personally find it a bad idea to define multiple components in the same file.
When I get an entity name in an instantiation, my first instinct is to start
looking for a file with the same name as the entity.}\\
Yes it is not a good idea but also create a file for each small entity it is not nice. These entity are
double flopping, triple flopping, rising and falling edge detection so are all grouped inside one file.\\
\item I corrected some English errors. For sure there are other errors. Apologize my English! :)
\end{itemize}
\newpage
\begin{center}
\LARGE{\textbf{Matthieu}}
\end{center}
\begin{itemize}
\item \textit{Change MBLT endian register name to SWAP configuration register
(or something similar).}\\
Done.\\
MBLT Endian register renamed Endian since it can be used during all the access
modes except during the CR/CSR accesses.
\item \textit{Add a reset output port on core's top level.}\\
In the VME64xCore\_Top's output port there is already a reset\_o signal which is active high and it comes from the software reset bit in the CRS space.
\item I deleted some of the not used signals.
\item \textit{Update the Manifest file.}\\
Done
\item now, you should not see same of the warnings you indicated to me in your
review.
\end{itemize}
\newpage
In the VME64xCore\_Top.vhd file it is possible to find the following generic paramiters:\\
\begin{itemize}
\item g\_clock
\item g\_wb\_data\_width.
\item g\_wb\_addr\_width.
\item g\_cram\_size.
\item g\_BoardID.
\item g\_ManufacturerID.
\item g\_RevisionID.
\item g\_ProgramID.
\end{itemize}
In the VME\_IRQ\_Controller.vhd component, the ACK\_INT state has been renamed CHECK; less confusing\\
During this first review I focused more on the timing problems, not synthesizable processes and so on.
I started from the (!) serious and (m) medium advices and I tried
to answer all the questions. \\
I deleted more or less all the never used signals and processes related to the 2emodes and the buffer not implemented. In so doing the project is less
confusing and clearer.\\
I tested again the vme64x core after making changes and it is still working fine.\\
I cannot see further timing rules violated.\\
\end{document}
General stuff
--------------------------------------------------------------------------------
I really like the fact that you wrote a lot of comments in the file headers. These
are very descriptive and very easy to read, which helps users quickly get up to
speed on how they can use your core in their design.
I hope the following will not demoralize you too much, because I'm going to
start with the things that should be improved. Feel free to step into the next
office and smack me one if you feel demoralized. :)
First thing I notice all across your designs is that your naming standards are
inconsistent. You combine camelCasing with PascalCasing and c_or_vhdl_style_casing,
which at least for me makes the code a little hard to read. This can either be
from you, or from the inherited code, so I can't complain too much about that. I
realize that changing signal naming at this particular moment in time would
pretty much be a pain in the ass and a long process, so I don't know what to
advise you in this respect.
What I would advise is to at least have the ports follow CERN HDL naming
conventions. That is, name input ports with an _i suffix, output ports
with a _o suffix and bidirectional ports with _b suffix. In this way, somebody
who has used CERN HDL before will be able to read your code much easier.
It might also help to have some comments accompanying your entity ports. This can
help users quickly instantiate your core (or components of your core), in case
they need them.
Another fairly bothersome thing is the fact that your ISE project is not portable.
When I tried to synthesize your design, it was asking me for locating the
design sources.
You have some more detailed comments below.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
VME_Access_Decode.vhd
--------------------------------------------------------------------------------
- line 8: typo
"This component check [...]"
should be:
"This component checkS [...]"
- line 20: typo
"[...] the block diagram the main component are two [...]"
should be
"[...] the block diagram the main componentS are two [...]"
or
"[...] there are two main components in the block diagram [...]"
- line 66: the "!!!" at the end is a bit aggressive towards the reader :)
I would advise you to change it to a full stop (".") or a simple exclamation
mark ("!")
- line 71: typo:
"corrisponding" -> "corresponding"
- line 83:
typos:
"corrisponding" -> "corresponding"
"the VME Master need to know", should be either
"the VME Masters need to know", or
"the VME Master needs to know"
- line 87: typo
"corrisponding" -> "corresponding"
- line 91: typos
"eg: lets imagine" -> "let's imagine"
"we want be able to access" -> "we want to (be able TO) access"
- line 93: typo:
"corrisponding" -> "corresponding"
- line 106: typo
"[...] so we need of two functions [...]" -> "[...] so we need two functions
[...]"
--------------------------------------------------------------------------------
VME_Am_Decode.vhd
--------------------------------------------------------------------------------
I would not encourage using VHDL code in the comments to describe what you want
to do. I mean here things like in line 13, where you say "AmMatch <= [...]",
and particularly things like "to_integer(unsigned([...]))".
Comments are supposed to be verbose descriptions of what your design does, avoid
using code inside your comments. The reader can read and understand the code
himself. If you *must* use code that you think makes your comments more
understandable, try to make your code as simple as possible. Using "to_integer"
and its lengthy brothers adds unnecessary details that can otherwise be
easily understood by the reader.
- line 9: typo
"corrispondent" -> "corresponding"
- lines 11-13: maybe you could make the comments a little clearer; at the moment
they seem a bit fuzzy to me, you have a bunch of unfinished sentences there that
don't make too much sense.
- line 14: typo
"[...] different address wide [...]" -> "[...] different address widths [...]"
- last two processes:
I find the first statements in these processes redundant. Do they help any by
being there?
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
ram_8bits.vhd
spram.vhd
xwb_ram.vhd
--------------------------------------------------------------------------------
There is an undefined constant here -- c_SIZE, that you are using to initialize
your g_size generic. However, this constant is not defined anywhere in the context
of these files. I tried finding it in the vme64x_pack.vhd file as well, but it's
not defined there.
You should either use predefined values for these generics, or defined this
constant somewhere in a package and "use" it in your design sources. I would
recommend the former.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
VME_bus.vhd
--------------------------------------------------------------------------------
- lines 362-375: the table's column lines are not aligned in some places.
- line 378: were you using TAB characterts to align the components of your
with..select statement? I would assume yes, because in my editor the second and
third assignment of the multiplexer are unaligned with the first, and the other
11 assignments are unaligned with the first three. Using SPACE characters to
align these statements (and others in general) would probably be a better idea.
You can also configure your editor to insert SPACE characters instead of TABs
This can make your code aligned irrespective of the machine or the reader's
editor.
I can see you have quite a few similar statements following; I will try to list
them out here, to make it easier for you to change them.
- line 395: funny indentation on the with..select
- line 429: funny indentation on the with..select
- line 444: funny indentation in the process
- line 470: funny indentation in the with..select
- lines 525-532: comments are unaligned, probably another TAB-related issue?
- line 638: funny indentation
- lines 643-649: funny indentation in the if statement
- line 653: funny indentation
- lines 750-758: funny indentation on the (twice commented) if statement
- lines 857-860: funny indentation on the (twice commented) if statement
- lines 881-884: funny indentation
- line 907: funny indentation
- line 911: funny indentation
- line 1034: the if statement in this process has a rather looooooooong condition
in the elsif part. I would advise you to use a vector whose bits are set
according to each of your conditions, and then check for that vector inside the
elsif. That, or anything that might make the code more readable. It's hard to
think anyone would bother reading a 7-line condition. True that you explain what
you are doing in the comment preceding the process, but still... Try to make
that statement more readable. It can only do us good!
- line 1054: typo: "overflow" -> "overflows"
- lines 1167-1176: you could align the two with..select statements a little
better, to make the code look nicer
- lines 1309-1330 : Again, the if statement in this process is a bit hard to read
both due to the long conditions, as well as some indenting issues.
- lines 1382-1448: the signal assignment operators in this process are too far
away from the signals. It would be a lot easier to read if you get them closer
to the signals.
- line 1456: funny indent
- line 1478: funny indent
- lines 1547-1561: it is a bit hard to read these statements; due to the many
conditions you have, it is hard to separate assignments from conditions.
- lines 1778-1785: place these statements in order -- led(0), led(1), led(2), etc.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
VME_CR_CSR_Space.vhd
--------------------------------------------------------------------------------
- line 9: typo:
"[...] CR/CSR space is used so is possible [...]"
->
"[...] CR/CSR space is used so IT is possible [...]"
- line 11: typo
" mode are selected the write operation will not be successful."
->
" modeS are selected [...]"
- line 47: "storaged" -> "stored"
a bit aggressive with the "!!" here :)
- line 127: funky indentation on the generic
- line 158: funky indentation on the port
- lines 178, 179: funky indentation on the signals
- lines 184-193: I would indent these lines
- line 220: indent
- lines 222-277: Aren't the to_integer()'s in the case statement redundant? Or
is it just because of the case in line 263?
- lines 280-284: you might want to fix the indent here
- line 353: indent
- line 381: indent
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
VME_CR_pack.vhd
--------------------------------------------------------------------------------
- lines 37-59: I suggest you put the constant values in hex. They are a lot more
readable than binary...
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
VME_CSR_pack.vhd
--------------------------------------------------------------------------------
- lines 40-84: indent these to make the code more readable
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
VME_Funct_Match.vhd
--------------------------------------------------------------------------------
- line 9: "corrisponding" -> "corresponding"
- line 10: "subtract" -> "subtracted"
- line 13: "here one example" -> "here IS one example"
- line 29: "the master access" -> "the master accessES"
- line 32: "the master write" -> "the master writeS"
- line 33: "the master want access at the location"
-> "the master wantS to access the location"
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
VME_Init.vhd
--------------------------------------------------------------------------------
- lines 157, 171: You could add a comment describing what each of these process
does. The process starting in line 171 is particularly hard to follow, so a
comment would help a great deal here.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
VME_IRQ_Controller.vhd
--------------------------------------------------------------------------------
- Nice FSM drawing! You should however check line 33, it's not aligned to line 34
- line 107, 130, 133, 134, 139: indent...
- lines 251-253: keep the same indent as the rest of the IF statement
- line 298: indent
- line 316: this is actually a Moore FSM (outputs depend only on current state)
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
VME_SharedComps.vhd
--------------------------------------------------------------------------------
I personally find it a bad idea to define multiple components in the same file.
When I get an entity name in an instantiation, my first instinct is to start
looking for a file with the same name as the entity.
Once again, I am aware that this might come from the person before you, but I
would strongly recommend to make the design more modular and easier to get
around, by placing all those components in its separate file.
- line 122: indent...
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
VME_swapper.vhd
--------------------------------------------------------------------------------
- lines 39, 74, 86, 98, 110, 122, 134, 146, 158: indent
--------------------------------------------------------------------------------
Severity:
(!) - serious
(m) - medium
(_) - cosmetic
(o) - optimization
General:
- (m) avoid std_logic_unsigned/std_logic_arith libraries. These are Synopsys's own libraries
(although widesperad and more-or-less supported by every tool), being slowly phased out.
Use numeric_std instead, which the official standard.
- (m) comment ports and generics in each module.
Top Level:
- (_) Process at lines 530+: I would place it in VME_bus. This way the top level module will only
act as an interconnect putting together all VME core components.
SharedComps:
- (!) place "KEEP" attribute in synchronizer chain modules to make sure Xilinx's software wont
try to optimize/merge them. Switch off LUT-based shift register inference for these blocks.
VME_Access_Decode:
- (_) I would recommend grouping the ader/amcap/xamcap ports into an array of records, this makes the code
much easier to read and maintain.
- (!) process driving cardsel and base_addr: sequential nonblocking assignments are potentially
dangerous - you are relying on assumption that if any of bits in s_func_sel is 1, cardsel (previously set
to 0) will be overwritten by the loop. It's safer to use variables and blocking assignments in such cases.
- (o) provide a generic allowing for reduction of device functions. In most cases, we need only 1 A24/A32/D32 BAR.
Decoding and storing BAR configurations takes large percentage of the FPGA resources consumed by the VME core.
VME_CR_CSR_Space:
- (m) lines 223+ (case statement) wouldn't it be simpler to do the slicing / zero padding in case statement or adjust
the constants in the package file instead of appending zeroes and slicing in each case entry?
- (m) GADER_1 loop: please put a single-line comment describing what the generate loop does.
VME_IRQ_Controller:
- (!) line 235: is reset signal active low or high?
VME_bus:
- (m) don't comment out code that is not used. Just remove it.
Coding style:
--------------
- (_) pass the code via indenting tool (emacs Ctrl-C/Ctrl-B for example)
- (m) _i/_o/_b suffixes on ports, g_ prefixes on generics, c_ prefixes on constants
- (_) avoid comments that do not provide any useful information (for example:
"----------------- entity declaration --- (lots of dashes....)" followed by "entity (".
----------------------------------------------------
--
-- Unit Name : Vme_intfce
--
--
-- This unit provides:
-- *A generic and basic Vme slave interface between the Vme bus and internal logic inside the FPGA
-- *A VME interrupter (ROACK type).
--
-- Supported/Not supported:
--
-- *Vme Data (read/write) operations (extended/standard/short address mode and 32-, 16- and 8-bit data words)
-- *Vme interrupt cycles (ROACK interrupter)(IRQ level and IRQ statusID to be feed externally (ie. via a register)
-- *No difference is made between supervisory/non privilege mode (AM(2) from VME bus is not used)
-- => Address modifiers are only 5 bits.
-- *Valid AM values are generated inside the entity according to the AddressWidth parameter
-- (see Note2 below).
-- *Unaligned data are not supported, so address positions must be even
-- *Different Direction polarity for data bus (dir='0' means read from the VME slave or dir='0'
-- means write into the VME slave)
--
-- *VME Read-Modify-Write cycles are also supported.
--
-- *Address only cycles are not supported.
--
-- Interface details:
--
-- VME side :
-- *Bi-directional buffers for Data bus already infered inside this entity
-- *Every line is registered (inputs and outputs)excepts IackOutN (see Vme spec.) =>latency
-- Internal side:
-- Outputs are registered and inputs are expected to be registered.This interface provides:
-- *ReadMem, AddrMem, DataToMem, WriteMem: 1 clock cycle asserted = 1 valid data/operation
-- to be done.
-- *IntProcessed : inform internal logic that the requested interrupt has been processed
-- (StatusID has been written in the Vme bus)
-- *UserIntReqN :internal logic requests an interrupt (any level) with this single line.
-- Has to be asserted low until IntProcessed is asserted by the VME interface.
-- *IrqLevelReg : The interrupt level to be requested/acknowleged in the Vme bus
-- *IRQStatusIDReg : StatusID to be fed into the Vme bus during interrupt cycle
-- *OpFinishedOut : Tells the internal logic the VME operation (read/write/interrupt) has finished
-- (VmeAsNA='1' and VmeDs0NA ='1' and VmeDs1NA='1'). Active by level
-- Generics :
-- *DataWidth : The Width of the Data words for Data transfers. Possible values are 32, 16 or 8
-- *AddressWidth : possible values are 32, 24 or 16
-- *BaseAddrWidth : any within the correct range (<AddressWidth).
-- *DirSamePolarity : Bidirectional buffers in the board (like ABT16245)need a direction pin and
-- bidirectional data pins.
-- The direction pin may have the same polarity as the bidirectional buffers in Xilinx Spartan or not.
-- if direction='1' means the VME bus IS WRITING INTO the SLAVE then SET DirSamePolarity='0'.
-- If direction='1' means the VME bus IS READING FROM the SLAVE then SET DirSamePolarity='1'.
--
-- *InterruptEn : Enables/Disables the interrupter functionnality of the VME interface
-- ('1'=Enabled '0'=Disabled).
--
--
--
-- Note2: Address Modifier used in the module:
--
-- ModuleAm :std_logic_vector (4 downto 0):= "11110" is generated automaticaly in the VME interface
-- according to the AddressWidth generic parameter.
-- Two moduleAm are generated: for word by word data transfer (ModuleAmNormal) or block data transfer (ModuleAmBlock).
-- Line AM(2) from VME bus is not taken into account, so:
-- moduleAm(4): AM (5) from VME bus
-- moduleAm(3): AM(4) from VME
-- moduleAm(2): AM(3) from VME
-- moduleAm(1): AM(1) from VME
-- moduleAm(0): AM(0) from VME
--
-- Notation : see Notation.vhd
--
--
--
--
-- Author : Rev 1 David Dominguez Montejos
-- Rev 2 Pablo Alvarez
-- Division: AB/CO
--
-- Revisions: 1.0: No Block transfer in VME side. (October 2002)
--
-- 1.1: DirSamePolarity generic,Changes in DataWidth, AddrWidth and BaseAddrWidth generics
-- (instead of DataWidth=31 now is 32, etc. Same for AddrWidth, etc.).
-- VmeDir and VmeDtackN are never tristated, if this feature is needed
-- (to connect several VME interfaces to the same lines) a wrapper (VmeWrap.vhd and VmeWrapped.vhd)
-- must be used. Block transfer are supported both reading and writing. Odd addresses may be read
-- when using 8-bit data words (Unaligned data for 8bit-data words).
-- New VmeDataUnAlign port added. Extended address access added. Read-Modify-Write cycles supported.
-- Metastibility problem in signal VmeAsNA solved. (January 2003)
--
-- 2.0 Antiglitch filter. Every VME signal transition has to be stable during at least 3 clk cycles
-- before it is validated. Block transfer and data unaligned features not implemented (October 2007).
--
--
-- 2.1 Watchdog added. DataFromMemValid replaced by DataReadDone, DataWriteDone (17 oct 2007)
-- 2.2 Write out of mem space bug fixed
-- For any bug or comment, please send an e-mail to pablo.alvarez.sanchez@cern.ch
------------------------------------------------------
library ieee;
use ieee.STD_LOGIC_1164.all;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity Vme_intfce is
generic ( AddrWidth : integer :=32;
BaseAddrWidth : integer :=8;
DataWidth : integer :=16;
InterruptEn : std_logic :='1';
WatchDogTop : integer := 80
);
port (
RstN : in std_logic;
Clk : in std_logic;
VmeAddrA : in std_logic_vector(AddrWidth-1 downto 1 );
VmeAsNA : in std_logic;
VmeDs1NA : in std_logic;
VmeDs0NA : in std_logic;
VmeData : inout std_logic_vector(DataWidth-1 downto 0 );
VmeDir : out std_logic;
-- VmeDirFloat : out std_logic;
VmeBufOeN : out std_logic;
VmeWriteNA : in std_logic;
VmeLwordNA : in std_logic;
VmeIackNA : in std_logic;
IackOutNA : out std_logic;
IackInNA : in std_logic;
VmeIntReqN : out std_logic_vector (7 downto 1);
vmeDtackN : out std_logic;
ModuleAddr : in std_logic_vector(BaseAddrWidth-1 downto 0 );
VmeAmA : in std_logic_vector(4 downto 0 );
AddrMem : out std_logic_vector(AddrWidth-BaseAddrWidth-1 downto 0 );
ReadMem : out std_logic;
WriteMem : out std_logic;
DataReadDone : in std_logic;
DataWriteDone : in std_logic;
DataFromMem : in std_logic_vector(DataWidth-1 downto 0 );
DataToMem : out std_logic_vector(DataWidth-1 downto 0 );
IntProcessed : out std_logic;
UserIntReqN : in std_logic;
-- UserBlocks : in std_logic;
IRQLevelReg : in std_logic_vector (3 downto 1);
IRQStatusIDReg: in std_logic_vector (DataWidth-1 downto 0)
---------------------------------------- debugging
-- VmeState : out std_logic_vector (3 downto 0)
--This signal is intended for debugging purposes and tells
-- the state of the VME interface.
----------------------------------------
);
end Vme_intfce;
architecture beh of Vme_intfce is
type VmeContInCellType is
record
VmeAddr : std_logic_vector(AddrWidth-1 downto 1 );
VmeAsN : std_logic;
VmeDs : std_logic_vector(1 downto 0);
VmeWriteN : std_logic;
VmeLwordN : std_logic;
VmeIackN : std_logic;
IackInN : std_logic;
ModuleAddr : std_logic_vector(BaseAddrWidth-1 downto 0 );
VmeAm : std_logic_vector(4 downto 0 );
end record VmeContInCellType;
signal VMECONTAREF : VmeContInCellType;
signal vmeContInD1, vmeContInD2, vmeContInD3 : VmeContInCellType;
signal vmeContInStable, vmeDataInStable, vmeAsInStable : std_logic;
signal vmeContInC, vmeDataInC, vmeAsInC : unsigned(3 downto 0);
constant TOPSTABLE : unsigned(3 downto 0) := to_unsigned(3,4);
IMPURE function CheckBus(vmeContIn : VmeContInCellType;
VMECONTREF : VmeContInCellType;
VmeStable : std_logic;
-- IrqReq : std_logic;
intLevel : std_logic_vector(3 downto 1)) return std_logic_vector is
variable RDWR : std_logic_vector(3 downto 0);
variable isWrite : std_logic;
variable isRead : std_logic;
variable isInte : std_logic;
variable isAnInt : std_logic;
begin
isWrite := '0';
isRead := '0';
isInte := '0';
isAnInt := '0' ;
if vmeContIn.VmeAsN = '0' then
if vmeContIn.VmeAddr(vmeContIn.VmeAddr'left downto vmeContIn.VmeAddr'left-ModuleAddr'left) = vmeContIn.ModuleAddr then
if vmeContIn.VmeAm = VMECONTREF.VmeAm then
if vmeContIn.VmeDs = VMECONTREF.VmeDs then
if vmeContIn.VmeLwordN = VMECONTREF.VmeLwordN then
if vmeContIn.IackInN = '1' then
if vmeContIn.VmeWriteN = '1' then
isRead := VmeStable;
else
isWrite := VmeStable;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
-- if vmeContIn.VmeDs = VMECONTREF.VmeDs then
if vmeContIn.IackInN = '0' then
if vmeContIn.VmeAsN = '0' then
if vmeContIn.VmeAddr(3 downto 1) = intLevel then
isInte := VmeStable ;
end if;
isAnInt := VmeStable ;
end if;
end if;
-- end if;
RDWR := isAnInt&isInte&isWrite&isRead;
return RDWR;
end CheckBus;
type states is (idle, rdCycle, putDataOnBus, wrCycle, waitWrDone, waitWrAsEnd, passIack, putIntVector);
signal nxst, st : states;
signal nxVmeData, vmeDataInD1, vmeDataInD2, vmeDataInD3, iVmeData : std_logic_vector(DataWidth-1 downto 0 );
--signal nxVmeDataUnAlign: std_logic_vector(UnalignDataWidth-1 downto 0);
signal nxVmeDir : std_logic;
--signal nxVmeDirFloat : std_logic;
--signal nxVmeBufOeN : std_logic;
signal nxIackOutNA : std_logic;
signal nxVmeIntReqN, convMyIntLevel : std_logic_vector (7 downto 1);
signal nxvmeDtackN : std_logic;
signal isRW : std_logic_vector(3 downto 0);
signal isRd, isInt, isWr, isAnInt: std_logic;
signal nxReadMem, nxWriteMem, nxIntProcessed, lVmeData, iWriteMem, iVmeDir: std_logic;
--signal watchDogC : unsigned(7 downto 0);
begin
VMECONTAREF.VmeIackN <= '1';
VMECONTAREF.IackInN <= '1';
VMECONTAREF.VmeAsN <= '0';
VMECONTAREF.VmeWriteN <= '0';
VMECONTAREF.VmeAddr <= (others => '0');
-----------------------------------------------------------
-----------------------------------------------------------
GD32: if DataWidth = 32 generate
VMECONTAREF.VmeDs <= "00"; --32 bit Data
VMECONTAREF.VmeLwordN <= '0';--32 bit Data
end generate;
GD16:if DataWidth = 16 generate
VMECONTAREF.VmeDs <= "00"; --16 bit Data
VMECONTAREF.VmeLwordN <= '1';--16 bit Data
end generate;
GD8: if DataWidth = 8 generate
VMECONTAREF.VmeDs <= "10"; --8 bit Data
VMECONTAREF.VmeLwordN <= '1';--8 bit Data
end generate;
-----------------------------------------------------------
GA32:if AddrWidth = 32 generate
VMECONTAREF.ModuleAddr <= (others => '0');
VMECONTAREF.VmeAm <= "00101"; --24 bit ADD
end generate;
GA24: if AddrWidth = 24 generate
VMECONTAREF.ModuleAddr <= (others => '0');
VMECONTAREF.VmeAm <= "11101"; --24 bit ADD
end generate;
GA16:if AddrWidth = 16 generate
VMECONTAREF.ModuleAddr <= (others => '0');
VMECONTAREF.VmeAm <= "10101"; --16 bit ADD
end generate;
-----------------------------------------------------------
-----------------------------------------------------------
isRW <= CheckBus(vmeContInD3, VMECONTAREF, vmeContInStable, IRQLevelReg);
isRd <= isRW(0);
isWr <= isRW(1);
isInt <= isRW(2);
isAnInt <= isRW(3);
process(clk)
begin
if rising_edge(clk) then
vmeContInD1.VmeAddr <= VmeAddrA;
vmeContInD1.VmeAsN <= VmeAsNA;
vmeContInD1.VmeDs(1) <= VmeDs1NA;
vmeContInD1.VmeDs(0) <= VmeDs0NA;
vmeContInD1.VmeWriteN <= VmeWriteNA;
vmeContInD1.VmeLwordN <= VmeLwordNA;
vmeContInD1.VmeIackN <= VmeIackNA;
vmeContInD1.IackInN <= IackInNA;
vmeContInD1.ModuleAddr <= ModuleAddr;
vmeContInD1.VmeAm <= VmeAmA;
vmeContInD2 <= vmeContInD1;
vmeContInD3 <= vmeContInD2;
vmeDataInD1 <= vmeData;
vmeDataInD2 <= vmeDataInD1;
vmeDataInD3 <= vmeDataInD2;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
if RstN = '0' then
vmeContInC <= to_unsigned(0, vmeContInC'length);
vmeContInStable <= '0';
else
if vmeContInD3 /= vmeContInD2 then
vmeContInC <= to_unsigned(0, vmeContInC'length);
elsif vmeContInC < TOPSTABLE then
vmeContInC <= vmeContInC + 1;
elsif vmeContInC > TOPSTABLE then
vmeContInC <= to_unsigned(0, vmeContInC'length);
end if;
if vmeContInD3 /= vmeContInD2 then
vmeContInStable <= '0';
elsif vmeContInC < TOPSTABLE then
vmeContInStable <= '0';
elsif vmeContInC = TOPSTABLE then
vmeContInStable <= '1';
else
vmeContInStable <= '0';
end if;
end if;
end if;
end process;
---------------------------------------------------
process(clk)
begin
if rising_edge(clk) then
if RstN = '0' then
vmeDataInC <= to_unsigned(0, vmeDataInC'length);
vmeDataInStable <= '0';
else
if vmeDataInD3 /= vmeDataInD2 then
vmeDataInC <= to_unsigned(0, vmeDataInC'length);
elsif vmeDataInC < TOPSTABLE then
vmeDataInC <= vmeDataInC + 1;
elsif vmeDataInC > TOPSTABLE then
vmeDataInC <= to_unsigned(0, vmeDataInC'length);
end if;
if vmeDataInD3 /= vmeDataInD2 then
vmeDataInStable <= '0';
elsif vmeDataInC < TOPSTABLE then
vmeDataInStable <= '0';
elsif vmeDataInC = TOPSTABLE then
vmeDataInStable <= '1';
else
vmeDataInStable <= '0';
end if;
end if;
end if;
end process;
---------------------------------------------------
process(clk)
begin
if rising_edge(clk) then
if RstN = '0' then
vmeAsInC <= to_unsigned(0, vmeAsInC'length);
vmeAsInStable <= '0';
else
if vmeContInD3.VmeAsN /= vmeContInD2.VmeAsN then
vmeAsInC <= to_unsigned(0, vmeAsInC'length);
elsif vmeAsInC < TOPSTABLE then
vmeAsInC <= vmeAsInC + 1;
elsif vmeAsInC > TOPSTABLE then
vmeAsInC <= to_unsigned(0, vmeAsInC'length);
end if;
if vmeContInD3.VmeAsN /= vmeContInD2.VmeAsN then
vmeAsInStable <= '0';
elsif vmeAsInC < TOPSTABLE then
vmeAsInStable <= '0';
elsif vmeAsInC = TOPSTABLE then
vmeAsInStable <= '1';
else
vmeAsInStable <= '0';
end if;
end if;
end if;
end process;
process(St, vmeContInStable, isAnInt, isWr, isRd, isInt, UserIntReqN, DataReadDone, DataWriteDone, vmeAsInStable, vmeContInD3, vmeDataInStable)
begin
case St is
when idle =>
if (isInt= '1') and (UserIntReqN='0') then
nxSt <= putIntVector;
elsif (isAnInt = '1') then
nxSt <= passIack;
elsif (isWr = '1') then
nxSt <= wrCycle;
elsif (isRd = '1') then
nxSt <= rdCycle;
-- if (vmeAddr_in (3 downto 1)= MyIrqLevel) and (UserIntReqN='0') then
else
nxSt <= idle;
end if;
-- end if;
when rdCycle =>
if DataReadDone = '1' then
nxSt <= putDataOnBus;
-- elsif watchDogC = to_unsigned(0,watchDogC'length) then
elsif vmeAsInStable = '1' and vmeContInD3.VmeAsN = '1' then
nxSt <= idle;
else
nxSt <= rdCycle;
end if;
when putDataOnBus =>
if vmeAsInStable = '1' and vmeContInD3.VmeAsN = '1' then
nxSt <= idle;
else
nxSt <= putDataOnBus;
end if;
when wrCycle =>
if vmeDataInStable = '1' then
nxSt <= waitWrDone;
else
nxSt <= wrCycle;
end if;
when waitWrDone =>
if DataWriteDone = '1' then
nxSt <= waitWrAsEnd;
-- elsif watchDogC = to_unsigned(0,watchDogC'length) then
-- nxSt <= idle;
elsif vmeAsInStable = '1' and vmeContInD3.VmeAsN = '1' then
nxSt <= idle;
else
nxSt <= waitWrDone;
end if;
when waitWrAsEnd =>
if vmeAsInStable = '1' and vmeContInD3.VmeAsN = '1' then
nxSt <= idle;
else
nxSt <= waitWrAsEnd;
end if;
when putIntVector =>
if vmeAsInStable = '1' and vmeContInD3.VmeAsN = '1' then
nxSt <= idle;
else
nxSt <= putIntVector;
end if;
when passIack =>
if vmeContInD3.IackInN = '1' and vmeContInD3.VmeAsN = '1' then
nxSt <= idle;
else
nxSt <= passIack;
end if;
when others =>
nxSt <= idle;
end case;
end process;
--------------------------------------------------------------
process(St, nxSt, IRQStatusIDReg, DataFromMem, DataReadDone, DataWriteDone, vmeDataInStable, IRQStatusIDReg)
begin
nxVmeData <= (others => '0');
nxVmeDir <= '1';
nxIackOutNA <= '1';
nxVmeIntReqN <= (others => '1');
nxvmeDtackN <= '1';
nxReadMem <= '0';
nxWriteMem <='0';
-- nxDataToMem <= '0';
nxIntProcessed <= '0';
-- nxOpFinishedOut <= '0';
lVmeData <= '0';
nxIackOutNA <= '1';
-- decWatchDog <= '1';
case St is
when idle =>
if nxSt = rdCycle then
nxReadMem <= '1';
end if;
if nxSt = putIntVector then
lVmeData <= '1';
nxVmeData <= IRQStatusIDReg;
nxIntProcessed <= '1';
end if;
-- decWatchDog <= '0';
when rdCycle =>
nxVmeData <= DataFromMem;
nxVmeDir <= not DataReadDone;
lVmeData <= DataReadDone;
when putDataOnBus =>
nxVmeDir <= '0';
nxVmeIntReqN <= (others => '1');
nxvmeDtackN <= '0';
when wrCycle =>
nxVmeDir <= '1';
nxVmeIntReqN <= (others => '1');
nxWriteMem <= vmeDataInStable;
when waitWrDone =>
nxvmeDtackN <= not DataWriteDone;
when waitWrAsEnd =>
nxvmeDtackN <= '0';
when putIntVector =>
nxVmeData <= IRQStatusIDReg;
nxVmeDir <= '0';
nxvmeDtackN <= '0';
-- decWatchDog <= '0';
when passIack =>
nxIackOutNA <= '0';
-- decWatchDog <= '0';
when others =>
end case;
end process;
--------------------------------------------------------------
process(Clk)
begin
if rising_edge(Clk) then
if (RstN = '0') then --or (watchDogC = to_unsigned(0,watchDogC'length)) then
st<= idle;
else
st <= nxSt;
end if;
end if;
end process;
--------------------------------------------------------------
process(Clk)
begin
if rising_edge(Clk) then
if RstN = '0' then
iVmeDir <= '0';
IackOutNA <= '1';
VmeIntReqN <= (others => '1');
vmeDtackN <= '1';
ReadMem <= '0';
iWriteMem <='0';
IntProcessed <= '0';
-- watchDogC <= to_unsigned(WatchDogTop, watchDogC'length);
-- arbiterLock <= '0';
else
iVmeDir <= nxVmeDir;
IackOutNA <= nxIackOutNA;
VmeIntReqN <= nxVmeIntReqN;
vmeDtackN <= nxvmeDtackN;
ReadMem <= nxReadMem;
iWriteMem <=nxWriteMem;
IntProcessed <= nxIntProcessed;
if nxIntProcessed = '1' then
VmeIntReqN <= (others =>'1');
elsif UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
end if;
-- if decWatchDog = '1' then
-- watchDogC <= watchDogC - 1;
-- else
-- watchDogC <= to_unsigned(WatchDogTop, watchDogC'length);
-- end if;
-- if DataFromMemValid = '1' then
-- arbiterLock <= '0';
-- elsif iWriteMem = '1' then
-- arbiterLock <= '1';
-- end if;
end if;
if nxWriteMem = '1' then
DataToMem <= vmeDataInD3;
end if;
if nxWriteMem = '1' or nxReadMem = '1' then
AddrMem <= vmeContInD2.VmeAddr(AddrMem'left downto 1)&'0';
end if;
if lVmeData = '1' then
iVmeData <= nxVmeData;
end if;
end if;
-- IntProcessed <= resetInt;
end process;
WriteMem <= iWriteMem;
VmeDir <= iVmeDir;
--------------------------------------------------------------
process(IRQLevelReg)
begin
case IRQLevelReg is
when "001" => convMyIntLevel <= "1111110";
when "010" => convMyIntLevel <= "1111101";
when "011" => convMyIntLevel <= "1111011";
when "100" => convMyIntLevel <= "1110111";
when "101" => convMyIntLevel <= "1101111";
when "110" => convMyIntLevel <= "1011111";
when "111" => convMyIntLevel <= "0111111";
when others => convMyIntLevel <="1111111";
end case;
end process;
VmeData <= iVmeData when iVmeDir = '0' else (others => 'Z');
--------------------------------------------------------------
VmeBufOeN <= '0';
end beh;
-- VHDL Test Bench Created from source file topbic.vhd -- 16:24:27 02/09/2004
--
-- Notes:
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation
-- simulation model.
--
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.mddef.all;
use work.headers.all;
use work.vme.all;
use work.vmesim.all;
use work.IntContPackage.all;
use IEEE.math_real.uniform;
use work.ctrpcomponents.all;
use work.CountersPackage.all;
ENTITY CtrvS3_tb IS
END CtrvS3_tb;
ARCHITECTURE behavior OF CtrvS3_tb IS
component CtrV
Generic(
VHDLVERSION : integer := 1186393929; --defined in DatePackage
VcxoTICKSLENGTH : integer := 26;
AddrWidth : integer :=24;
BaseAddrWidth : integer :=8;
DataWidth : integer :=32;
DirSamePolarity : std_logic :='0';
UnalignDataWidth : integer := 8;
InterruptEn : std_logic :='1'
);
Port (
RstNA : in std_logic;
Vcxo : in std_logic; -- 40 MHz iVcxo Clock
XGClk : in std_logic; -- Local Incorrelated Quartz Oscillator
ExtClk1 : in std_logic; -- External Clk 1
ExtClk2 : in std_logic; -- External Clk 2
XExtStart : in std_logic_vector(2 downto 1);
-- LemoOut : out std_logic_vector(7 downto 0);
Gmt : in std_logic;
-- GmtDir : out std_logic;
-- GmtOut : out std_logic;
CalIn : in std_logic;
CalDir : out std_logic;
CalOut : out std_logic;
-- XGpsMhz : in std_logic;
-- GmtClkDir : out std_logic;
-- GmtClkOut : out std_logic;
CtrvVer : in std_logic_vector(2 downto 0);
-- HTDC
-- OutEnable : out std_logic;
TdchIt : out std_logic_vector(31 downto 0);
TdcData : in std_logic_vector(31 downto 0);
TdcTest : in std_logic;
TdcError : in std_logic;
TdcDRdy : in std_logic;
TdctRst : out std_logic;
TdcTck : out std_logic;
TdcTms : out std_logic;
TdcTdi : out std_logic;
TdcTdo : in std_logic;
TdcReset : out std_logic;
TdcTrigger : out std_logic;
TdcBChReset : out std_logic;
TdcEvReset : out std_logic;
TdcGetData : out std_logic;
-- VME
VmeAddrA : in std_logic_vector(AddrWidth-1 downto 1 );
VmeAsNA : in std_logic;
VmeDs1NA : in std_logic;
VmeDs0NA : in std_logic;
VmeData : inout std_logic_vector(DataWidth-1 downto 0 );
-- VmeDataUnAlign: inout std_logic_vector(UnalignDataWidth-1 downto 0);
VmeDir : out std_logic;
-- VmeDirFloat : out std_logic;
VmeBufOeN : out std_logic_vector(3 downto 0);
VmeWriteNA : in std_logic;
VmeLwordNA : in std_logic;
VmeIackNA : in std_logic;
IackOutNA : out std_logic;
IackInNA : in std_logic;
-- VmeIntReqN : out std_logic_vector (7 downto 1);
VmeIntReqN2 : out std_logic;
VmeIntReqN3 : out std_logic;
vmeDtackN : out std_logic;
ModuleAddr : in std_logic_vector(3 downto 0 );
VmeAmA : in std_logic_vector(5 downto 0 );
-- PLL Control
-- DAC
DacClrN : out std_logic; -- Clear
DacData : out std_logic; -- Data
DacClk : out std_logic; -- DAC Clk
DacCsN : out std_logic; -- Chip Select
-- iVcxo
VcxoTtl : out std_logic; -- TTL/CMOS Selection
-- DT71V35761/781 synchronous RAM
-- RamAdd : out std_logic_vector(16 downto 0); -- Address Inputs
-- -- Synchronous Address inputs. The address register is triggered by a combination of the
-- -- rising edge of iVcxo and RamADSCN Low or RamADSPN Low and RamCEN Low.
--
-- RamData : inout std_logic_vector(31 downto 0); -- Synchronous data input/output pins. Both
-- -- the data input path and data output path are registered and triggered by the rising edge
-- -- of iVcxo
-- RamDataPar : inout std_logic_vector(3 downto 0); -- Data parity
---- RamZZ : out std_logic; -- Sleep Mode.
-- -- Data Retention is garanteed in Sleep Mode
--
-- RamOEN : out std_logic; -- Asynchronous output enable. When
-- -- RamOEN is LOW the data output drivers are enabled on the RamData pins if the chip is also selected.
-- -- When RamOEN is HIGH the RamData pins are in high impedance state.
-- RamLBON : out std_logic; -- Linear Burst Order
-- -- Asynchronous burst order selection input. When RamLBON is HIGH, the interleaved burst sequence
-- -- is selected. When RamLBON is LOW the Linear burst sequence is selected. RamLBON is a static
-- -- input and must not change state while the device is operating!!!
--
-- RamGWN : out std_logic; --Synchronous global write enable.
-- -- This input will write all four 9-bit data bytes when LOW on the rising edge of iVcxo.
-- -- RamGWN supersedes individual byte write enables.
--
-- RamCEN : out std_logic; -- Synchronous chip enable.
-- -- RamCEN is used with RamCS0 and RamCS1N to enable the IDT71V35761/781. RamCEN also gates RamADSPN.
--
---- RamCS0 : out std_logic; -- Synchronous active HIGH chip select.
-- -- RamCS0 is used with RamCEN and RamCS1N to enable the chip.
--
---- RamCS1N : out std_logic; --Synchronous active LOW chip select.
-- -- RamCS1N is used with RamCEN and RamCS0 to enable the chip.
--
-- RamWRN : out std_logic; --Synchronous byte write enable
-- -- gates the byte write inputs BW1-BW4. If BWE is LOW at the
-- -- rising edge of CLK then BWx inputs are passed to the next stage in the circuit. If BWE is
-- -- HIGH then the byte write inputs are blocked and only GW can initiate a write cycle.
--
-- RamBWN : out std_logic_vector(4 downto 1); -- Individual Write Enables
-- -- Synchronous byte write enables. BW1 controls I/O0-7, I/OP1, BW2 controls I/O8-15, I/OP2, etc.
-- -- Any active byte write causes all outputs to be disabled.
--
-- RamADVN : out std_logic; -- Burst Address Advance
-- -- Advance Synchronous Address Advance. RamADVN is an active LOW input that is used to advance the
-- -- internal burst counter, controlling burst access after the initial address is loaded. When the
-- -- input is HIGH the burst counter is not incremented; that is, there is no address advance.
--
-- RamADSPN : out std_logic; -- Address Status (Processor)
-- -- Synchronous Address Status from Processor. RamADSPN is an active LOW IDT71V35761 input that is used to
-- -- load the address registers with new addresses. RamADSPN is gated by RamCEN.
--
-- RamADSCN : out std_logic; -- Address Status (Cache Controller)
-- -- Synchronous Address Status from Cache Controller. RamADSCN is an active LOW input that is
-- -- used to load the address registers with new addresses.
--
--
-- XORamClk40 : out std_logic;
---- XIRamClk40 : in std_logic;
--
-- Other Pins
-- Leds
-- XOutLed : out std_logic_vector(4 downto 1);
XIrqLed : out std_logic;
XTimingLed : out std_logic;
-- XBUSLed : out std_logic;
-- XExtStartLED : out std_logic_vector(1 downto 0);
XPllLockedLed : out std_logic;
XUserIO: out std_logic_vector(64 downto 1);
XOKLed : out std_logic;
UIOByte: out std_logic_vector(7 downto 0);
XEnabledLed : out std_logic;
PwResetN : in std_logic;
XExtClk1Led : out std_logic;
XExtClk2Led : out std_logic;
XMuxCtrl : out std_logic;
FrontPannelOE : out std_logic;
-- Temperature : in std_logic;
SerialId : inout std_logic;
KHzOut : out std_logic
-- Init_b : out std_logic;
-- DIN_DO : out std_logic
);
--*******
end component CtrV;
------------------------------------------------------
component idt71v35761s183
port (
A : in std_logic_vector(16 downto 0);
D : inout std_logic_vector(31 downto 0);
DP : inout std_logic_vector(3 downto 0);
oe_N : in std_logic;
ce_N : in std_logic;
cs0 : in std_logic;
cs1_N : in std_logic;
lbo_N : in std_logic;
gw_N: in std_logic;
bwe_N : in std_logic;
bw4_N : in std_logic;
bw3_N : in std_logic;
bw2_N : in std_logic;
bw1_N : in std_logic;
adsp_N : in std_logic;
adsc_N : in std_logic;
adv_N : in std_logic;
clk : in std_logic
);
end component idt71v35761s183;
-----------------------------------------------------
type MESSMEM_type is array (Natural Range <> ) of message_type;
--signal mesTable : mesTableType;
signal refFstMebIndex : integer := 0;
----------------------------------
----------------------------------
signal mesin : message_type;
signal start : std_logic;
signal mdo : std_logic;
signal done : std_logic;
signal frameData : std_logic_vector(15 downto 0) ;
signal parityType : std_logic_vector(3 downto 0) := X"0";
--signal enableGmt : boolean;
-----------------------------------------------------
SIGNAL RstNA : std_logic;
SIGNAL Vcxo : std_logic; -- 40 MHz iVcxo Clock
SIGNAL XGClk : std_logic; -- Local Incorrelated Quartz Oscillator
SIGNAL ExtClk1 : std_logic; -- External Clk 1
SIGNAL ExtClk2 : std_logic; -- External Clk 2
SIGNAL XExtStart : std_logic_vector(2 downto 1);
-- HTDC
SIGNAL TdchIt : std_logic_vector(31 downto 0);
SIGNAL TdcData : std_logic_vector(31 downto 0);
SIGNAL TdcTest : std_logic;
SIGNAL TdcError : std_logic;
SIGNAL TdcDRdy : std_logic;
SIGNAL TdctRst : std_logic;
SIGNAL TdcTck : std_logic;
SIGNAL TdcTms : std_logic;
SIGNAL TdcTdi : std_logic;
SIGNAL TdcTdo : std_logic;
SIGNAL TdcReset : std_logic;
SIGNAL TdcTrigger : std_logic;
SIGNAL TdcBChReset : std_logic;
SIGNAL TdcEvReset : std_logic;
SIGNAL TdcGetData : std_logic;
-----------------------------------------------------
SIGNAL DacClrN : std_logic; -- Clear
SIGNAL DacData : std_logic; -- Data
SIGNAL DacClk : std_logic; -- DAC Clk
SIGNAL DacCsN : std_logic; -- Chip Select
-- iVcxo
SIGNAL VcxoTtl : std_logic; -- TTL/CMOS Selection
-- DT71V35761/781 synchronous RAM
SIGNAL RamAdd : std_logic_vector(16 downto 0); -- Address Inputs
-- Synchronous Address inputs. The address register is triggered by a combination of the
-- rising edge of iVcxo and RamADSCN Low or RamADSPN Low and RamCEN Low.
SIGNAL RamData : std_logic_vector(31 downto 0); -- Synchronous data input/output pins. Both
-- the data input path and data output path are registered and triggered by the rising edge
-- of iVcxo
SIGNAL RamPar : std_logic_vector(4 downto 1); -- Data parity
-- RamZZ : out std_logic; -- Sleep Mode.
-- Data Retention is garanteed in Sleep Mode
SIGNAL RamOEN : std_logic; -- Asynchronous output enable. When
-- RamOEN is LOW the data output drivers are enabled on the RamData pins if the chip is also selected.
-- When RamOEN is HIGH the RamData pins are in high impedance state.
SIGNAL RamLBON : std_logic; -- Linear Burst Order
-- Asynchronous burst order selection input. When RamLBON is HIGH, the interleaved burst sequence
-- is selected. When RamLBON is LOW the Linear burst sequence is selected. RamLBON is a static
-- input and must not change state while the device is operating!!!
SIGNAL RamGWN : std_logic; --Synchronous global write enable.
-- This input will write all four 9-bit data bytes when LOW on the rising edge of iVcxo.
-- RamGWN supersedes individual byte write enables.
SIGNAL RamCEN : std_logic; -- Synchronous chip enable.
-- RamCEN is used with RamCS0 and RamCS1N to enable the IDT71V35761/781. RamCEN also gates RamADSPN.
SIGNAL RamBWN : std_logic_vector(4 downto 1); -- Individual Write Enables
-- Synchronous byte write enables. BW1 controls I/O0-7, I/OP1, BW2 controls I/O8-15, I/OP2, etc.
-- Any active byte write causes all outputs to be disabled.
SIGNAL RamADVN : std_logic; -- Burst Address Advance
-- Advance Synchronous Address Advance. RamADVN is an active LOW input that is used to advance the
-- internal burst counter, controlling burst access after the initial address is loaded. When the
-- input is HIGH the burst counter is not incremented; that is, there is no address advance.
SIGNAL RamADSPN : std_logic; -- Address Status (Processor)
-- Synchronous Address Status from Processor. RamADSPN is an active LOW IDT71V35761 input that is used to
-- load the address registers with new addresses. RamADSPN is gated by RamCEN.
SIGNAL RamADSCN : std_logic; -- Address Status (Cache Controller)
-- Synchronous Address Status from Cache Controller. RamADSCN is an active LOW input that is
-- used to load the address registers with new addresses.
SIGNAL RamWRN: std_logic;
SIGNAL RamDataPar: std_logic_vector(3 downto 0);
SIGNAL XORamClk40 : std_logic;
-- XIRamClk40 : in std_logic;
-- Other Pins
-- Leds
-- XOutLed : out std_logic_vector(4 downto 1);
SIGNAL XTimingLed : std_logic;
-- XBUSLed : out std_logic;
-- XExtStartLED : out std_logic_vector(1 downto 0);
SIGNAL XExtClk1Led : std_logic;
SIGNAL XExtClk2Led : std_logic;
SIGNAL XGPSMHz: std_logic;
SIGNAL XEnabledLed: std_logic;
SIGNAL XOKLed: std_logic;
SIGNAL XIrqLed: std_logic;
SIGNAL XPllLockedLed: std_logic;
SIGNAL PwResetN: std_logic;
SIGNAL XUserIO: std_logic_vector(64 downto 1);
SIGNAL UIOByte: std_logic_vector(7 downto 0);
SIGNAL XMuxCtrl : std_logic;
SIGNAL Gmt : std_logic;
------------------------------
----------------------------------------------
----------------------------------------------
-- SIGNAL RstNA : std_logic;
SIGNAL Clk : std_logic;
SIGNAL VmeDirTri : std_logic;
SIGNAL VmeDtackNTri : std_logic;
SIGNAL Clk10Mhz : std_logic;
SIGNAL Spare2FO : std_logic;
SIGNAL XTEST : std_logic_vector(3 downto 0);
----------------------------------
----------------------------------
-- Vme signals
----------------------------------
----------------------------------
signal VmeAddrA : std_logic_vector(23 downto 1 );
signal VmeAmA : std_logic_vector(5 downto 0 );
signal VmeAsNA : std_logic;
signal VmeDs1NA : std_logic;
signal VmeDs0NA : std_logic;
signal VmeDataA : std_logic_vector(31 downto 0 );
signal VmeDir : std_logic;
-- signal sVmeBufOeN : std_logic;
signal VmeBufOeN : std_logic_vector(3 downto 0);
signal VmeWriteNA : std_logic;
signal VmeLwordNA: std_logic;
signal VmeIackNA : std_logic;
signal IackOutNA: std_logic;
signal IackInNA : std_logic;
signal VmeIntReqN : std_logic_vector(7 downto 0 );
signal VmeIntReqN2 : std_logic; -- VME interrupt request
signal VmeIntReqN3 : std_logic; -- VME interrupt request
signal VmeDtackN : std_logic;
signal ModuleAddr : std_logic_vector(3 downto 0);
signal vmeBusOutArray : VmeBusOutRecordArray(2 downto 0);
signal vmeBusOut : vmeBusOutRecord;
signal vmeBusIn : VmeBusInRecord;
signal writeFinished, readFinished : boolean;
signal TestVmeAddr : std_logic_vector(23 downto 0 );
signal enableGmt : boolean := true;
SIGNAL mask_register : std_logic_vector(7 downto 0);
signal addofset : integer range 0 to 100000;
signal onestd : std_logic := '1';
signal zerostd, clke1,rst : std_logic := '0';
BEGIN
trx : me
port map (reset => RstNA,
clk => vcxo,
clke1 => clke1, -- Enable to have 1 MHz clock.
mesin => mesin,
--parityType => parityType,
start => start,
mdo => mdo,
done => done);
gmt <= not mdo;
process
begin
clke1 <= '0';
--wait for 500 ns;
while true loop
wait until rising_edge(Vcxo);
clke1 <= '1';
wait until rising_edge(Vcxo);
clke1 <= '0';
wait for 1 us - 28 ns;
end loop;
end process;
process
begin
if enableGmt then
start <= '1';
else
start <= '0';
end if;
wait for 10 ns;
start <= '0';
wait for 125 us - 10 ns;
end process;
--************************************************************
--************************************************************
--************************************************************
process
variable vFrameData : std_logic_vector(15 downto 0);
variable vSlotNumber : integer :=0;
variable vMili : integer := 900;
variable vUnix : integer := 4;
variable u1 : integer := 3;
variable u2 : integer := 7;
variable vRand : real;
variable vMiliS : integer ;
variable vUnixStd : std_logic_vector(31 downto 0);
begin
uniform(seed1 => u1,seed2 => u2,x => vRand);
vFrameData := (others => '0');
if vSlotNumber = 0 then
if (vMili mod 5) /= 2 then
mesin(0) <= MILLISECOND_HEADER;
vFrameData := CONV_STD_LOGIC_VECTOR(vMiliS, 16);
report "milisegundo" severity note;
else
mesin(0) <= (others => '0');
vFrameData := (others => '0');
end if;
vMili := (vMili + 1) mod 10 ;
vMiliS := vMili + 990;
elsif (vMili) = 2 then
if vSlotNumber = 1 then
vUnixStd := CONV_STD_LOGIC_VECTOR(vUnix, vUnixStd'left + 1);
mesin(0) <= UNIX_HEADER_LOW(31 downto 24);
mesin(1) <= UNIX_HEADER_LOW(23 downto 16);
vFrameData := vUnixStd(15 downto 0);
report "segundo enviado parte baja" severity note;
elsif vSlotNumber = 3 then
mesin(0) <= UNIX_TIME_START(31 downto 24);
mesin(1) <= UNIX_TIME_START(23 downto 16);
vFrameData := vUnixStd(31 downto 16);
report "segundo enviado parte alta" severity note;
vUnix := vUnix + 1;
elsif vSlotNumber = 4 then
mesin(0) <= x"14";
mesin(1) <= x"05";
-- vFrameData := vUnixStd(31 downto 16);
report "UNIX_TIME_START enviado" severity note;
-- vUnix := vUnix + 1;
else
mesin(0) <= (others => '0');
vFrameData := (others => '0');
end if;
else
mesin(0) <= (others => '0');
mesin(1) <= (others => '0');
--frame(MILLISECOND_HEADER'right - 1 downto 0) <= CONV_STD_LOGIC_VECTOR(integer(vRand*real(integer'left)), MILLISECOND_HEADER'right);
end if;
mesin(2) <= vFrameData(15 downto 8);
mesin(3) <= vFrameData(7 downto 0);
vSlotNumber := (vSlotNumber + 1) mod 8;
wait until rising_edge(start);
end process;
--************************************************************
--************************************************************
--************************************************************
paritytype <= "0000";
uut: CtrV
Port map(
RstNA => RstNA,
Vcxo => Vcxo, -- 40 MHz iVcxo Clock
XGClk => XGClk, -- Local Incorrelated Quartz Oscillator
ExtClk1 => ExtClk1, -- External Clk 1
ExtClk2 => ExtClk2, -- External Clk 2
XExtStart => XExtStart,
-- HTDC
TdchIt => TdchIt,
TdcData => TdcData,
TdcTest => TdcTest,
TdcError => TdcError,
TdcDRdy => TdcDRdy,
TdctRst => TdctRst,
TdcTck => TdcTck,
TdcTms => TdcTms,
TdcTdi => TdcTdi,
TdcTdo => TdcTdo,
TdcReset => TdcReset,
TdcTrigger => TdcTrigger,
TdcBChReset => TdcBChReset,
TdcEvReset => TdcEvReset,
TdcGetData => TdcGetData,
-- VME
VmeAddrA => VmeAddrA,
VmeAsNA => VmeAsNA,
VmeDs1NA => VmeDs1NA,
VmeDs0NA => VmeDs0NA,
VmeData => VmeDataA,
-- VmeDataUnAlign => open,
VmeDir => VmeDir,
-- VmeDirFloat : out std_logic;
VmeBufOeN => VmeBufOeN,
VmeWriteNA => VmeWriteNA,
VmeLwordNA => VmeLwordNA,
VmeIackNA => VmeIackNA,
IackOutNA => IackOutNA,
IackInNA => IackInNA,
-- VmeIntReqN : out std_logic_vector (7 downto 1);
VmeIntReqN2 => VmeIntReqN2,
VmeIntReqN3 => VmeIntReqN3,
vmeDtackN => vmeDtackN,
ModuleAddr => ModuleAddr,
VmeAmA => VmeAmA,
-- PLL Control
-- DAC
DacClrN => DacClrN, -- Clear
DacData => DacData, -- Data
DacClk => DacClk, -- DAC Clk
DacCsN => DacCsN, -- Chip Select
-- iVcxo
VcxoTtl => VcxoTtl, -- TTL/CMOS Selection
-- DT71V35761/781 synchronous RAM
-- RamAdd => RamAdd, -- Address Inputs
-- -- Synchronous Address inputs. The address register is triggered by a combination of the
-- -- rising edge of iVcxo and RamADSCN Low or RamADSPN Low and RamCEN Low.
--
-- RamData => RamData, -- Synchronous data input/output pins. Both
-- -- the data input path and data output path are registered and triggered by the rising edge
-- -- of iVcxo
---- RamPar => RamPar, -- Data parity
---- RamZZ : out std_logic; -- Sleep Mode.
-- -- Data Retention is garanteed in Sleep Mode
--
-- RamOEN => RamOEN, -- Asynchronous output enable. When
-- -- RamOEN is LOW the data output drivers are enabled on the RamData pins if the chip is also selected.
-- -- When RamOEN is HIGH the RamData pins are in high impedance state.
-- RamLBON => RamLBON, -- Linear Burst Order
-- -- Asynchronous burst order selection input. When RamLBON is HIGH, the interleaved burst sequence
-- -- is selected. When RamLBON is LOW the Linear burst sequence is selected. RamLBON is a static
-- -- input and must not change state while the device is operating!!!
--
-- RamGWN => RamGWN, --Synchronous global write enable.
-- -- This input will write all four 9-bit data bytes when LOW on the rising edge of iVcxo.
-- -- RamGWN supersedes individual byte write enables.
--
-- RamCEN => RamCEN, -- Synchronous chip enable.
-- -- RamCEN is used with RamCS0 and RamCS1N to enable the IDT71V35761/781. RamCEN also gates RamADSPN.
--
---- RamCS0 : out std_logic; -- Synchronous active HIGH chip select.
-- -- RamCS0 is used with RamCEN and RamCS1N to enable the chip.
--
---- RamCS1N : out std_logic; --Synchronous active LOW chip select.
-- -- RamCS1N is used with RamCEN and RamCS0 to enable the chip.
--
---- RamBWEN : out std_logic; --Synchronous byte write enable
-- -- gates the byte write inputs BW1-BW4. If BWE is LOW at the
-- -- rising edge of CLK then BWx inputs are passed to the next stage in the circuit. If BWE is
-- -- HIGH then the byte write inputs are blocked and only GW can initiate a write cycle.
--
-- RamBWN => RamBWN, -- Individual Write Enables
-- -- Synchronous byte write enables. BW1 controls I/O0-7, I/OP1, BW2 controls I/O8-15, I/OP2, etc.
-- -- Any active byte write causes all outputs to be disabled.
--
-- RamADVN => RamADVN, -- Burst Address Advance
-- -- Advance Synchronous Address Advance. RamADVN is an active LOW input that is used to advance the
-- -- internal burst counter, controlling burst access after the initial address is loaded. When the
-- -- input is HIGH the burst counter is not incremented; that is, there is no address advance.
--
-- RamADSPN => RamADSPN, -- Address Status (Processor)
-- -- Synchronous Address Status from Processor. RamADSPN is an active LOW IDT71V35761 input that is used to
-- -- load the address registers with new addresses. RamADSPN is gated by RamCEN.
--
-- RamADSCN => RamADSCN, -- Address Status (Cache Controller)
-- -- Synchronous Address Status from Cache Controller. RamADSCN is an active LOW input that is
-- -- used to load the address registers with new addresses.
--
-- -- RamWRN => RamWRN,
-- -- RamDataPar => RamDataPar,
--
-- XORamClk40 => XORamClk40,
---- XIRamClk40 : in std_logic;
--
--
--
-- Other Pins
-- Leds
-- XOutLed : out std_logic_vector(4 downto 1);
XTimingLed => XTimingLed,
-- XBUSLed : out std_logic;
-- XExtStartLED : out std_logic_vector(1 downto 0);
XExtClk1Led => XExtClk1Led,
XExtClk2Led => XExtClk2Led,
-- XGPSMHz => XGPSMHz,
XEnabledLed => XEnabledLed,
XOKLed => XOKLed,
XIrqLed => XIrqLed,
XPllLockedLed => XPllLockedLed,
PwResetN => PwResetN,
XUserIO => XUserIO,
UIOByte => UIOByte,
XMuxCtrl => XMuxCtrl,
Gmt => mdo,
CalIn => '0',
CalDir => open,
CalOut =>open,
-- XGpsMhz : in std_logic;
-- GmtClkDir : out std_logic;
-- GmtClkOut : out std_logic;
CtrvVer => "000"
);
RstNA <= '0', '1' after 1467 ns;
rst <= not RstNA;
--******************************************************************
PROCESS
BEGIN
Vcxo <= '1';
wait for 25000 ps /2;
Vcxo <= '0';
wait for 25000 ps /2;
END PROCESS;
--******************************************************************
PROCESS
BEGIN
XGClk <= '1';
wait for 22353 ps /2;
XGClk <= '0';
wait for 22353 ps /2;
END PROCESS;
Uidt71v35761s183 :idt71v35761s183 port map(
A => RamAdd,
D => RamData,
DP => RamPar,
oe_N => RamOEN,
ce_N => RamCEN,
cs0 => onestd,
cs1_N => zerostd,
lbo_N => RamLBON,
gw_N => RamGWN,
bwe_N => onestd,
bw4_N => RamBWN(4),
bw3_N => RamBWN(3),
bw2_N => RamBWN(2),
bw1_N => RamBWN(1),
adsp_N => RamADSPN,
adsc_N => RamADSCN,
adv_N => RamADVN,
clk => XORamClk40
);
------------------------------------------------------------------------
-----------------------------------------------------------------------
-- Parte copiada del test bench del VME
------------------------------------------------------------------------
--------------------------------------------
--------------------------------------------
vmeBusOut <= PullUpVmeBusOut(vmeBusOutArray);
VmeAddrA <= vmeBusOut.VmeAddrA;
VmeAsNA <= vmeBusOut.VmeAsNA ;
VmeAmA <= "111001";--vmeBusOut.VmeAmA ;
VmeDs1NA <= vmeBusOut.VmeDs1NA;
VmeDs0NA <= vmeBusOut.VmeDs0NA;
VmeLwordNA<= vmeBusOut.VmeLwordNA;
VmeWriteNA <= vmeBusOut.VmeWriteNA;
VmeIackNA <= vmeBusOut.VmeIackNA ;
IackInNA <= vmeBusOut.IackInNA ;
VmeDataA <= vmeBusOut.VmeData when vmeBusIn.VmeDir = '1' else (others => 'Z');
writeFinished <= vmeBusOut.writeFinished;
readFinished <= vmeBusOut.readFinished;
TestVmeAddr <= VmeAddrA&'0';
--------------------------------------------
--------------------------------------------
vmeBusIn.VmeData <= VmeDataA; --VmeDataInA;
vmeBusIn.VmeDir <= VmeDir;
vmeBusIn.VmeBufOeN <= VmeBufOeN(0) when VmeBufOeN(0) = '0' else '1';
vmeBusIn.IackOutNA<= IackOutNA;
vmeBusIn.VmeAsNA <= VmeAsNA ;
vmeBusIn.VmeIntReqN <= VmeIntReqN;
vmeBusIn.dtack_n <= vmeDtackN;
VmeIntReqN <= "1111"&(VmeIntReqN3)&(VmeIntReqN2)&"11";
--------------------------------------------
--------------------------------------------
ModuleAddr <= not MODULE_ADDRESS_C(MODULE_ADDRESS_C'right +3 downto MODULE_ADDRESS_C'right);
--------------------------------------------
--------------------------------------------
interrupt_p : process
begin
wait until RstNA = '1';
InitVME(VmeBusIn => vmeBusIn, VmeBusOut => vmeBusOutArray(2));
wait for 10 us;
while true loop
TreatInterruptVme(VmeBusIn => vmeBusIn, VmeBusOut => vmeBusOutArray(2));
end loop;
wait;
end process;
statusregvme : process
variable vIntAdd : integer;
variable vResult, vVmeCell : VmeCellType;
variable vData : VmeDataType := X"0000AA00";
variable vIntAddData : IntAddDataType;
begin
wait until RstNA = '1';
InitVME(VmeBusIn => vmeBusIn, VmeBusOut => vmeBusOutArray(1));
vData := X"00000042";
wait for 1 us;
wait for 10 us;
WriteVMEC(VIntAdd => ADDTABLE(CommandP).AddL*2, VData => vData, VmeBusIn => VmeBusIn, VmeBusOut => vmeBusOutArray(1));
vData := X"00000302";
WriteVMEC(VIntAdd => ADDTABLE(PhaseDCMP).AddL*2+4, VData => vData, VmeBusIn => VmeBusIn, VmeBusOut => vmeBusOutArray(1));
-- wait for 10 us;
vData := X"0000ffff";
WriteVMEC(VIntAdd => ADDTABLE(InterruptEnableP).AddL*2, VData => vData, VmeBusIn => VmeBusIn, VmeBusOut => vmeBusOutArray(1));
ReadVMEC(VIntAdd => ADDTABLE(InterruptEnableP).AddL*2, VResult => vResult,
VmeBusIn => VmeBusIn, VmeBusOut => vmeBusOutArray(1));
ReadVMEC(VIntAdd => ADDTABLE(PhaseDCMP).AddL*2+4, VResult => vResult,
VmeBusIn => VmeBusIn, VmeBusOut => vmeBusOutArray(1));
vData(MODE_H_R downto MODE_L_R) := "01";
vData(ON_ZERO_H_R downto ON_ZERO_L_R) := "01";
vData(WIDTH_H_R downto WIDTH_L_R) := "00"&x"00008";
WriteVMEC(VIntAdd => ADDTABLE(ConfigP1).AddL*2, VData => vData, VmeBusIn => VmeBusIn, VmeBusOut => vmeBusOutArray(1));
vData := X"00000000";
WriteVMEC(VIntAdd => ADDTABLE(DelayP1).AddL*2, VData => vData, VmeBusIn => VmeBusIn, VmeBusOut => vmeBusOutArray(1));
wait for 10 ns;
-- f1: for I in ADDTABLE(CtrDrvrHwTriggerP).AddL to ADDTABLE(SyncRamP).AddH loop
-- vData := conv_std_logic_vector(I, vData'length);
-- wait for 1 ns;
-- WriteVMEC(VIntAdd => (I)*2, VData => vData, VmeBusIn => VmeBusIn, VmeBusOut => vmeBusOutArray(1));
-- end loop;
--
-- f2: for I in ADDTABLE(CtrDrvrHwTriggerP).AddL to ADDTABLE(SyncRamP).AddH loop
-- vIntAddData.Address := I*2;
-- vIntAddData.Data := conv_std_logic_vector(I, vData'length);
-- SetAddress(VIntAddData => vIntAddData, VVmeCell =>vVmeCell);
-- wait for 1 ns;
-- ReadVME(VVmeCell => vVmeCell, VResult => vResult,
-- VmeBusIn => VmeBusIn, VmeBusOut => vmeBusOutArray(1));
---- if vResult /= conv_std_logic_vector(I, vResult'length) then
---- report "bad data!!!!!!!!!!!!!!!!!!! Read:"&integer'image(conv_integer(vResult.Data))&"at add"&integer'image(I);
---- end if;
-- end loop;
wait;
end process;
END;
----------------------------------------------------
--
-- Unit Name : Vme_intfce
--
--
-- This unit provides:
-- *A generic and basic Vme slave interface between the Vme bus and internal logic inside the FPGA
-- *A VME interrupter (ROACK type).
--
-- Supported/Not supported:
--
-- *Vme Data (read/write) operations (extended/standard/short address mode and 32-, 16- and 8-bit data words)
-- *Vme Block transfer is supported for 32-,16- and 8-bit data words and 32-, 24- bit addresses. A maximum
-- of 256 data bytes are allowed in a blk transfer (see VME spec).
-- *Vme interrupt cycles (ROACK interrupter)(IRQ level and IRQ statusID to be feed externally (ie. via a register)
-- *No difference is made between supervisory/non privilege mode (AM(2) from VME bus is not used)
-- => Address modifiers are only 5 bits.
-- *Valid AM values are generated inside the entity according to the AddressWidth parameter
-- (see Note2 below).
-- *Unaligned data are not supported, so address positions must be even, except when using 8-bit
-- data words. In that case odd memory positions are processed both in normal and block transfers.
--
-- *Different Direction polarity for data bus (dir='0' means read from the VME slave or dir='0'
-- means write into the VME slave)
--
-- *VME Read-Modify-Write cycles are also supported.
--
-- *Address only cycles are not supported.
--
-- Interface details:
--
-- VME side :
-- *Bi-directional buffers for Data bus already infered inside this entity
-- *Every line is registered (inputs and outputs)excepts IackOutN (see Vme spec.) =>latency
-- *VmeDataUnAlign : this port is provided to support Unaligned data (only for 8-bits data words)
--
-- Internal side:
-- Outputs are registered and inputs are expected to be registered.This interface provides:
-- *ReadMem, AddrMem, DataToMem, WriteMem: 1 clock cycle asserted = 1 valid data/operation
-- to be done.
-- *IntProcessed : inform internal logic that the requested interrupt has been processed
-- (StatusID has been written in the Vme bus)
-- *UserIntReqN :internal logic requests an interrupt (any level) with this single line.
-- Has to be asserted low until IntProcessed is asserted by the VME interface.
-- *IrqLevelReg : The interrupt level to be requested/acknowleged in the Vme bus
-- *IRQStatusIDReg : StatusID to be fed into the Vme bus during interrupt cycle
-- *UserBlocks : internal logic may be interested in preventing the device from doing any
-- Read/write transaction. Active high.
-- *OpFinishedOut : Tells the internal logic the VME operation (read/write/interrupt) has finished
-- (VmeAsNA='1' and VmeDs0NA ='1' and VmeDs1NA='1'). Active by level
-- Generics :
-- *DataWidth : The Width of the Data words for Data transfers. Possible values are 32, 16 or 8
-- *UnalignDataWidth: When doing 8-bits data transfers the VME spec. states that byte0
-- (memory address 0) will be put in the lines Data8 to Data15, wereas byte1
-- (memory address 1) will be put in the lines Data0 to Data7. Therefore, even
-- if you are using 8-bits data words, the minimum size of the bus to be used is
-- 16 bits. Set this parameter to 8 if you use 8-bits data words and you need
-- the DataBus to be 16-bits wide. Only valid for 8-bits data words.
-- *AddressWidth : possible values are 32, 24 or 16
-- *BaseAddrWidth : any within the correct range (<AddressWidth).
-- *DirSamePolarity : Bidirectional buffers in the board (like ABT16245)need a direction pin and
-- bidirectional data pins.
-- The direction pin may have the same polarity as the bidirectional buffers in Xilinx Spartan or not.
-- if direction='1' means the VME bus IS WRITING INTO the SLAVE then SET DirSamePolarity='0'.
-- If direction='1' means the VME bus IS READING FROM the SLAVE then SET DirSamePolarity='1'.
--
-- *InterruptEn : Enables/Disables the interrupter functionnality of the VME interface
-- ('1'=Enabled '0'=Disabled).
--
--
--
-- Note2: Address Modifier used in the module:
--
-- ModuleAm :std_logic_vector (4 downto 0):= "11110" is generated automaticaly in the VME interface
-- according to the AddressWidth generic parameter.
-- Two moduleAm are generated: for word by word data transfer (ModuleAmNormal) or block data transfer (ModuleAmBlock).
-- Line AM(2) from VME bus is not taken into account, so:
-- moduleAm(4): AM (5) from VME bus
-- moduleAm(3): AM(4) from VME
-- moduleAm(2): AM(3) from VME
-- moduleAm(1): AM(1) from VME
-- moduleAm(0): AM(0) from VME
--
-- Notation : see Notation.vhd
--
--
--
--
-- Author : David Dominguez Montejos
-- Division: AB/CO
--
-- Revisions: 1.0: No Block transfer in VME side. (October 2002)
--
-- 1.1: DirSamePolarity generic,Changes in DataWidth, AddrWidth and BaseAddrWidth generics
-- (instead of DataWidth=31 now is 32, etc. Same for AddrWidth, etc.).
-- VmeDir and VmeDtackN are never tristated, if this feature is needed
-- (to connect several VME interfaces to the same lines) a wrapper (VmeWrap.vhd and VmeWrapped.vhd)
-- must be used. Block transfer are supported both reading and writing. Odd addresses may be read
-- when using 8-bit data words (Unaligned data for 8bit-data words).
-- New VmeDataUnAlign port added. Extended address access added. Read-Modify-Write cycles supported.
-- Metastibility problem in signal VmeAsNA solved. (January 2003)
--
--
-- For any bug or comment, please send an e-mail to David.Dominguez@cern.ch
------------------------------------------------------
library ieee;
use ieee.STD_LOGIC_1164.all;
use ieee.STD_LOGIC_ARITH.all;
use ieee.STD_LOGIC_UNSIGNED.all;
entity Vme_intfce is
generic ( AddrWidth : integer :=16;
BaseAddrWidth : integer :=8;
DataWidth : integer :=8;
DirSamePolarity : std_logic :='0';
UnalignDataWidth : integer := 8;
InterruptEn : std_logic :='1'
);
port (
RstN : in std_logic;
Clk : in std_logic;
VmeAddrA : in std_logic_vector(AddrWidth-1 downto 1 );
VmeAsNA : in std_logic;
VmeDs1NA : in std_logic;
VmeDs0NA : in std_logic;
VmeData : inout std_logic_vector(DataWidth-1 downto 0 );
VmeDataUnAlign: inout std_logic_vector(UnalignDataWidth-1 downto 0);
VmeDir : out std_logic;
VmeDirFloat : out std_logic;
VmeBufOeN : out std_logic;
VmeWriteNA : in std_logic;
VmeLwordNA : in std_logic;
VmeIackNA : in std_logic;
IackOutNA : out std_logic;
IackInNA : in std_logic;
VmeIntReqN : out std_logic_vector (7 downto 1);
vmeDtackN : out std_logic;
ModuleAddr : in std_logic_vector(BaseAddrWidth-1 downto 0 );
VmeAmA : in std_logic_vector(4 downto 0 );
AddrMem : out std_logic_vector(AddrWidth-BaseAddrWidth-1 downto 0 );
ReadMem : out std_logic;
WriteMem : out std_logic;
DataFromMemValid : in std_logic;
DataFromMem : in std_logic_vector(DataWidth-1 downto 0 );
DataToMem : out std_logic_vector(DataWidth-1 downto 0 );
IntProcessed : out std_logic;
UserIntReqN : in std_logic;
UserBlocks : in std_logic;
OpFinishedOut : out std_logic;
IRQLevelReg : in std_logic_vector (3 downto 1);
IRQStatusIDReg: in std_logic_vector (DataWidth-1 downto 0);
---------------------------------------- debugging
VmeState : out std_logic_vector (3 downto 0)
--This signal is intended for debugging purposes and tells
-- the state of the VME interface.
----------------------------------------
);
end Vme_intfce;
architecture Vme_intfce of Vme_intfce is
signal ds0N_in1 :std_logic;
signal ds1N_in1 :std_logic;
signal VmeAddr_in1 : std_logic_vector(AddrWidth -1 downto 1 );
signal am_in1 : std_logic_vector(4 downto 0 );
signal iackN_in1 :std_logic;
signal iackInN_in1 :std_logic;
signal asN_in1 :std_logic;
signal writeN_in1 :std_logic;
signal lwordN_in1 :std_logic;
-- signal vmeDataIn1:std_logic_vector(DataWidth-1 downto 0 );
signal vmeDataIn1 :std_logic_vector(DataWidth-1 downto 0 );
signal vmeDataOut :std_logic_vector(DataWidth-1 downto 0 );
signal vmeDataUnAlignIn :std_logic_vector(UnAlignDataWidth-1 downto 0 );
signal vmeDir_in :std_logic;
signal vmeDirN_in :std_logic;
signal odd : std_logic;
-- says if the address is even or odd
signal moduleSelected : std_logic;
signal moduleAmBlock : std_logic_vector (4 downto 0);
signal moduleAmNormal : std_logic_vector (4 downto 0);
signal intForMe : std_logic;
signal daisy : std_logic;
-- the token has arrived in the iackInN daisychain
signal writeN_in : std_logic;
signal lwordN_in : std_logic;
signal VmeAddr_in : std_logic_vector(AddrWidth -1 downto 1 );
signal dataFromMem_in : std_logic_vector (DataWidth-1 downto 0);
signal asN_in : std_logic;
signal ds0N_in : std_logic;
signal ds1N_in : std_logic;
signal am_in : std_logic_vector(4 downto 0 ); -- AM2 is not used
signal readGo : std_logic;
--The read cycle starts
signal writeGo : std_logic;
--The write cycle starts
signal iackN_in : std_logic;
signal IackInN_in : std_logic;
signal addr_in : std_logic_vector((AddrWidth-BaseAddrWidth -1) downto 0 );
signal intGo : std_logic;
--the Interrupt cycle starts (VmeIackN has been activated)
signal opFinished : std_logic;
--activates when a cycle is finished (asN_in,ds0N_in...='1')
signal goBlk : std_logic;
signal blkOp : std_logic;
--Address Modifier says it is a block operation
signal blkAddrInc : std_logic_vector (2 downto 0);
--depending on the data size, address may be incremented by 1,2 or 4
signal nextBlkData : std_logic;
--allow incrementing the address and fetch/store the next data
signal blkMax : std_logic_vector (7 downto 0);
-- VME spec does not allow BLK transf >256 Bytes or 128 words or 64 Dwords
signal blkCounter : std_logic_vector (7 downto 0);
--Number of data words in the blk transfer
signal dsNVectorOld,dsNVectorNew :std_logic_vector (1 downto 0);
--In blk transfer and Data=8 bits, DsN0 and DsN1 MUST alternate.
signal startOp, startInt : std_logic;
--check data Width before a Read/write or Int cycle starts
signal startRWM : std_logic;
--check the CPU has started the second part of the Read-Mod_write cycle
signal readModifWrite : std_logic;
-- it activates when a "Read-Modify-Write cycle is detected
signal myIrqLevel : std_logic_vector (3 downto 1);
signal statusID : std_logic_vector (DataWidth-1 downto 0);
signal convMyIntLevel : std_logic_vector (7 downto 1);
signal strobeSignals1, strobeSignals2 : std_logic_vector(30 downto 0);
signal strobeSignalsStable, dataSignalsStable: std_logic;
type states is (idle, IntCycle, Read, WaitRd, DtackNRead, DtackNInt, BlkWr, blkRd, DaisyArrived, DataOnVme,
DataWritten, WaitWr, NextRd, NextWr,RdModWr);
signal current, nexts : states;
begin
-- Assignments
OpFinishedOut <=opFinished;
DirPolarity0: if DirSamePolarity='0' generate
VmeDir <= vmeDirN_in;
end generate DirPolarity0;
DirPolarity1: if DirSamePolarity /='0' generate
VmeDir <= vmeDir_in;
end generate DirPolarity1;
UnalignedDataLines: if (UnalignDataWidth=8 and DataWidth=8)generate
VmeDataUnAlign <= vmeDataOut when vmeDir_in='1' else (others =>'Z');
vmeDataUnAlignIn <=VmeDataUnAlign;
end generate UnalignedDataLines;
IackOutgen0: if (InterruptEn='1') generate
IackOutNA <= VmeAsNA when (intForMe='0' and daisy='1') else '1';
--Do not use asN_in: maximum time required to deassert iack_out
--after asN goes up is 40ns
end generate IackOutgen0;
IackOutgen1: if (InterruptEn='0') generate
IackOutNA <= IackInNA; --Avoid any logic implementation for interrupts
end generate IackOutgen1; --if they are not used
VmeData <=vmeDataOut when vmeDir_in='1' else(others =>'Z');
-- vmeDataInA <=VmeData;
VmeBufOeN <='0';
myIrqlevel <=IRQLevelReg;
statusID <=IRQStatusIDReg;
AddrMem <=addr_in;
opfinished <='1' when (ds0N_in='1' and ds1N_in='1' and asN_in='1') else '0';
goBlk <= '1' when (ds0N_in ='1' and ds1N_in ='1' and asN_in='0' and blkOp ='1') else '0';
readModifWrite <= '1' when (ds0N_in ='1' and ds1N_in ='1' and asN_in='0' and blkOp ='0'
and current /= idle) else '0';
----------------------------
-- Start of generics section
----------------------------
moduleA1: if AddrWidth= 32 generate
--Bit AM(2) to choose between superv/non privilege is not
-- taken into account. Extended access
ModuleAmNormal <= "00101";
ModuleAmBlock <= "00111";
end generate moduleA1;
moduleA2: if AddrWidth= 24 generate
--Bit AM(2) to choose between superv/non privilege is not
-- taken into account. Standard access
ModuleAmNormal <= "11101";
ModuleAmBlock <= "11111";
end generate moduleA2;
moduleA3: if AddrWidth= 16 generate
-- Short access
--In short mode there is no block transfert. Using a
-- User defined range Am the block transfert is unavailable.
ModuleAmNormal <="10101";
ModuleAmBlock <= "01000" ;
end generate moduleA3;
moduleA4:if (AddrWidth /=32 and AddrWidth /=24 and AddrWidth /=16) generate
ModuleAmNormal <="01000"; --User defined range for Address Modifiers
ModuleAmBlock <="01000"; --No use in this interface
end generate moduleA4;
dataL1: if DataWidth= 32 generate
startOp <='1' when (ds0N_in='0' and ds1N_in='0' and asN_in='0'
and lwordN_in='0' and current= idle and iackN_in='1') else '0';
odd <='0';
startRWM <='1' when (ds0N_in='0' and ds1N_in='0' and asN_in='0'
and lwordN_in='0' and writeN_in='0') else '0';
nextBlkData <='1' when (asN_in ='0' and ds0N_in='0' and ds1N_in='0') else '0';
blkAddrInc <="100";
blkMax <= X"3F" ; --255 bytes/4= 63 longWords
-- When activating interrupts some DSC's may only activate ds0N regardless
-- of the real DataWidth
-- startInt <='1' when (ds0N_in='0' and ds1N_in='0' and asN_in='0'
-- and lwordN_in='0' and current= idle and iackN_in='0') else '0';
startInt <='1' when (ds0N_in='0' and asN_in='0' and current= idle
and iackN_in='0') else '0';
end generate dataL1;
dataL2: if DataWidth= 16 generate
startOp <='1' when (ds0N_in='0' and ds1N_in='0' and asN_in='0'
and lwordN_in='1' and current= idle and iackN_in='1') else '0';
odd <='0';
startRWM <='1' when (ds0N_in='0' and ds1N_in='0' and asN_in='0'
and lwordN_in='1' and writeN_in='0') else '0';
nextBlkData <='1' when (asN_in ='0' and ds0N_in='0' and ds1N_in='0') else '0';
blkAddrInc <="010";
blkMax <= X"7F"; --255 bytes/2= 127 Words
-- When activating interrupts some DSC's may only activate ds0N regardless
-- of the real DataWidth
-- startInt <='1' when (ds0N_in='0' and ds1N_in='0' and asN_in='0'
-- and current= idle and iackN_in='0') else '0';
startInt <='1' when (ds0N_in='0' and asN_in='0'
and current= idle and iackN_in='0') else '0';
end generate dataL2;
dataL3: if DataWidth=8 generate
startOp <='1' when (((ds0N_in='0' and ds1N_in='1')or (ds1N_in='0' and ds0N_in='1')) and asN_in='0'
and lwordN_in='1' and current= idle and iackN_in='1') else '0';
odd <= '1' when (ds0N_in='0' and ds1N_in ='1' and asN_in ='0'
and lwordN_in ='1' and iackN_in ='1') else '0';
startRWM <='1' when (((ds0N_in='0' and ds1N_in='1')or (ds1N_in='0' and ds0N_in='1')) and asN_in='0'
and lwordN_in='1'and writeN_in='0') else '0';
nextBlkData <='1' when ((ds0N_in='0' or ds1N_in='0') and asN_in ='0'
and (dsNVectorNew = not(dsNVectorOld))) else '0';
blkAddrInc <= "001";
blkMax <= X"FF" ; --255 bytes
startInt <='1' when (ds0N_in='0' and asN_in='0'
and current= idle and iackN_in='0') else '0';
end generate dataL3;
datal4: if (DataWidth /=32 and DataWidth /=16 and DataWidth /=8) generate
startOp <='0';
startInt <='0';
NextBlkData <='0';
odd <='0';
startRWM <='0';
blkAddrInc <= (others =>'0');
blkMax <= (others =>'0');
end generate dataL4;
----------------------------
-- End of generics section
----------------------------
--IRQ level to generate in the VME BUS
process (RstN, MyIrqLevel)
begin
convMyIntlevel <= (others =>'1');
if RstN ='0' then
convMyIntlevel <= (others =>'1');
else
case MyIrqLevel is
when "001" => convMyIntLevel <= "1111110";
when "010" => convMyIntLevel <= "1111101";
when "011" => convMyIntLevel <= "1111011";
when "100" => convMyIntLevel <= "1110111";
when "101" => convMyIntLevel <= "1101111";
when "110" => convMyIntLevel <= "1011111";
when "111" => convMyIntLevel <= "0111111";
when others => convMyIntLevel <="1111111";
end case;
end if;
end process;
--Process to assigne next state to current state
process (RstN,Clk,nexts)
begin
if rising_edge(Clk) then
if RstN='0' then
current <=idle;
else
current <= nexts ;
end if;
end if;
end process;
-- process to change the state signal and initialize
--internal signals
defineState: process (current,readGo,intGo,writeGo,DataFromMemValid,opFinished,
asN_in, iackInN_in,ds1N_in, ds0N_in, nextBlkData, goBlk,blkCounter,blkMax,
readModifWrite,startRWM )
begin
case current is
when idle =>
if readGo = '1' then nexts <=read;
elsif intGo= '1' then nexts <=intCycle;
elsif (writeGo = '1') then nexts <=dataWritten;
else nexts <=idle;
end if;
when read =>
if DataFromMemValid= '1' then nexts <= dataOnVme;
else nexts <= waitRd;
end if;
when dataOnVme =>
if opFinished = '1' then
nexts <=idle;
else
nexts <= DtackNRead;
end if;
when DtackNRead =>
if opFinished = '1' then
nexts <=idle;
elsif goBlk= '1' then
nexts <=blkRd;
elsif readModifWrite ='1' then
nexts <= RdModWr;
else
nexts <= DtackNRead;
--just wait for the DSC to set VmeASN ='1' and VmeDs0N='1'
--and VmeDs1N='1' or enter the next block data word
end if;
when RdModWr =>
if startRWM ='1' then
nexts <= DataWritten;
elsif opfinished='1' then
nexts <=idle;
else
nexts <= RdModWr;
end if;
when waitRd =>
if opfinished ='1' then
nexts <= idle;
elsif dataFromMemValid = '1' then
nexts <=dataOnVme;
else
nexts <=waitRd;
end if;
when blkRd =>
if opFinished='1' then
nexts <=idle;
elsif (nextBlkData ='1' and blkCounter < blkMax) then
nexts <= NextRd;
--If the maximum number of data in a block (see VME spec) has been
--reached, the slave will not process any extra word
--and will just wait forcing the VME Timer to generate a
-- bus error and avoid blocking the bus indefinitely
else
nexts <= blkRd;
end if;
when NextRd =>
if opfinished ='1' then
nexts <=idle;
elsif DataFromMemValid= '1' then
nexts <= dataOnVme;
else
nexts <= waitRd;
end if;
when dataWritten =>
if opFinished='1' then
nexts <=idle;
else
nexts <=waitWr;
end if;
when waitWr =>
if opFinished='1' then
nexts <=idle;
elsif goBlk= '1' then
nexts <=blkWr;
else
nexts <=waitWr;
end if;
when blkWr =>
if opFinished='1' then
nexts <=idle;
elsif (nextBlkData ='1' and blkCounter < blkMax) then
nexts <= NextWr;
else
nexts <=blkWr;
end if;
when NextWr =>
nexts <=WaitWr;
when IntCycle =>
if (asN_in ='1' and ds1N_in ='1' and ds0N_in='1') then
nexts <=idle;
--a different device with same
--irq level and before in the daisy
-- chain also wanted the irq
elsif (iackInN_in='0' and asN_in='0') then
nexts <=daisyArrived;
else nexts <=IntCycle;
end if;
when daisyArrived =>
if (asN_in ='1' and ds1N_in ='1' and ds0N_in='1') then
nexts <= idle;
else
nexts <= DtackNInt;
end if;
when DtackNInt =>
if (asN_in ='1' and ds1N_in ='1' and ds0N_in='1') then
nexts <= idle;
else
nexts <= DtackNInt;
end if;
when others => nexts <= idle;
end case;
end process defineState;
--Assigning the outputs according to the state signal
signal strobeSignals1, strobeSignals2 : std_logic_vector(30 downto 0);
signal strobeSignalsStable, dataSignalsStable: std_logic;
strobeSignals1 <= ds0N_in1&ds1N_in1&VmeAddr_in1&iackN_in1&iackInN_in1&asN_in1&writeN_in1&lwordN_in1;
strobeSignals2 <= ds0N_in&ds1N_in&VmeAddr_in&iackN_in&iackInN_in&asN_in&writeN_in&lwordN_in;
strobeSignalsStable <= '1' when strobeSignals1 = strobeSignals2;
dataSignalsStable <= '1' when vmeDataIn1 = vmeDataIn;
inputs: process (RstN,clk)
begin
if rising_edge(clk) then
ds0N_in1 <= VmeDs0NA;
ds1N_in1<=VmeDs1NA;
VmeAddr_in1 <= VmeAddrA;
am_in1 <= VmeAmA;
iackN_in1 <= VmeIackNA;
iackInN_in1 <=IackInNA;
asN_in1 <= VmeAsNA;
writeN_in1 <= VmeWriteNA;
lwordN_in1 <= VmeLwordNA;
vmeDataIn1 <= VmeData;
end if;
end process;
outputs: process (clk)
begin
if rising_edge(clk) then
if RstN='0' then
VmeDirFloat <='1';
VmeIntReqN <= (others =>'1');
moduleSelected <='0';
readGo <= '0';
writeGo <= '0';
intGo <= '0';
blkOp <='0';
blkCounter <= (others =>'0');
dsNVectorOld <="11";
dsNvectorNew <="11";
intForMe <='0';
ds0N_in <= '1';
ds1N_in <= '1';
asN_in <= '1';
addr_in <= (others => '0');
writeN_in <= '1';
lwordN_in <= '1';
am_in <=(others=>'0');
daisy <='0';
-- vmeDataOut <=(others =>'0');
-- DataToMem <=(others =>'0');
-- dataFromMem_in <= (others =>'0');
writeMem <='0';
readMem <='0';
vmeDir_in <='0';
vmeDirN_in <='1';
vmeDtackN <='1';
IntProcessed <='0';
iackn_in <='1';
iackinn_in <='1';
vmeaddr_in <=(others =>'0');
-- VMEstate <= (others =>'0');
else
ds0N_in <= ds0N_in1;
ds1N_in <=ds1N_in1;
VmeAddr_in <= VmeAddr_in1;
am_in <= am_in1 ;
iackN_in <= iackN_in1;
iackInN_in <=iackInN_in1;
asN_in <= asN_in1;
writeN_in <= writeN_in1;
lwordN_in <= lwordN_in1;
vmeDataIn <= vmeDataIn1;
if startOp='1' and moduleSelected='1' and UserBlocks='0' then
if writeN_in='1' then
readGo <='1';
writeGo <='0';
intGo <='0';
else
readGo <='0';
writeGo <='1';
intGo <='0';
end if;
elsif startInt='1' and InterruptEn='1' then
readGo <='0';
WriteGo <='0';
intGo <='1';
else
readGo <='0';
writeGo <='0';
intGo <='0';
end if;
case current is
when idle =>
VmeDirFloat <='1';
if ( VmeAddr_in(AddrWidth -1 downto (AddrWidth-BaseAddrWidth)) = ModuleAddr)
and (am_in = ModuleAmNormal or am_in =ModuleAmBlock)
and (asN_in ='0') then
moduleSelected <='1';
if am_in = ModuleAmBlock then
blkOp <='1';
else
blkOp <='0';
end if;
else
moduleSelected <='0';
end if;
vmeDtackN<='1';
blkCounter <= (others =>'0');
ReadMem <='0';
vmeDir_in <='0';
vmeDirN_in <='1';
intForMe <='0';
IntProcessed <='0';
WriteMem <='0';
--DataToMem <=(others =>'0');
daisy <='0';
VmeDataOut <=(others =>'0');
VMEstate <= (others =>'0');
if UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
else
VmeIntReqN <= (others =>'1');
end if;
when read =>
dsNvectorOld <= Ds1N_in & Ds0N_in;
dsNvectorNew <= Ds1N_in & Ds0N_in;
VmeDirFloat <='1';
vmeDir_in <='0';
vmeDirN_in <='1';
addr_in <= vmeAddr_in ((AddrWidth-BaseAddrWidth-1) downto 1)& odd;
ReadMem <= '1';
VMEstate <= "0001";
if UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
else
VmeIntReqN <= (others =>'1');
end if;
when intCycle =>
VmeDirFloat <='1';
if (vmeAddr_in (3 downto 1)= MyIrqLevel) and (UserIntReqN='0') then
intForMe <='1';
else
intForMe <='0';
end if;
VMEstate <= "1011";
if UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
else
VmeIntReqN <= (others =>'1');
end if;
when daisyArrived =>
if intForMe='1' then
VmeDirFloat <='0';
vmeDir_in <='1';
vmeDirN_in <='0';
VmeDataOut <=StatusId;
vmeDtackN <='1';
VmeIntReqN <=(others =>'1');
IntProcessed <='1';
elsif UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
else
VmeIntReqN <= (others =>'1');
end if;
daisy <='1';
VMEstate <= "1100";
when DtackNInt =>
if intForMe='1' then
VmeDirFloat <='0';
vmeDir_in <='1';
vmeDirN_in <='0';
VmeDataOut <=StatusId;
vmeDtackN <='0';
VmeIntReqN <=(others =>'1');
IntProcessed <='1';
else
if UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
else
VmeIntReqN <= (others =>'1');
end if;
VmeDirFloat <='1';
VmeDir_in <='0';
vmeDirN_in <='1';
VmeDtackN <='1';
end if;
daisy <='1';
VMEstate <= "1101";
when dataOnVme =>
VmeDirFloat <='0';
vmeDir_in <='1';
vmeDirN_in <='0';
VmeDataOut <=dataFromMem_in;
vmeDtackN <='1';
ReadMem <='0';
VMEstate <= "0011";
if UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
else
VmeIntReqN <= (others =>'1');
end if;
when DtackNRead =>
VmeDirFloat <='0';
vmeDir_in <='1';
vmeDirN_in <='0';
VmeDataOut <=dataFromMem_in;
vmeDtackN <='0';
ReadMem <='0';
VMEstate <= "0100";
if UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
else
VmeIntReqN <= (others =>'1');
end if;
when RdModWr =>
VmeDirFloat <= '0';
vmeDir_in <= '0';
vmeDirN_in <= '1';
vmeDtackN <= '1';
VmeState <= X"e";
if UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
else
VmeIntReqN <= (others =>'1');
end if;
when waitRd =>
ReadMem <='0';
dataFromMem_in <=DataFromMem;
VMEstate <= "0010";
if UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
else
VmeIntReqN <= (others =>'1');
end if;
when dataWritten =>
dsNvectorOld <= Ds1N_in & Ds0N_in;
dsNvectorNew <= Ds1N_in & Ds0N_in;
VmeDirFloat <='0';
vmeDir_in <='0';
vmeDirN_in <='1';
addr_in <= vmeAddr_in ((AddrWidth-BaseAddrWidth-1) downto 1) & odd;
if (UnalignDataWidth=8 and DataWidth=8 and odd='0') then
DataToMem <= vmeDataUnAlignIn (UnAlignDataWidth-1 downto 0) ;
else
DataToMem <= vmeDataIn (DataWidth-1 downto 0);
end if;
WriteMem <='1';
intForMe <='0';
vmeDtackN <='1';
VMEstate <= "0111";
if UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
else
VmeIntReqN <= (others =>'1');
end if;
when waitWr =>
VmeDirFloat <='0';
vmeDir_in <='0';
vmeDirN_in <='1';
WriteMem <='0';
VmeDtackN <='0';
VMEstate <= "1000";
if UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
else
VmeIntReqN <= (others =>'1');
end if;
when blkWr =>
dsNvectorNew <= Ds1N_in & Ds0N_in;
VmeDirFloat <= '0';
vmeDir_in <='0';
vmeDirN_in <='1';
WriteMem <='0';
VmeDtackN <='1';
VmeState <="1001";
if UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
else
VmeIntReqN <= (others =>'1');
end if;
when NextWr =>
dsNvectorOld <=dsNvectorNew;
VmeDirFloat <='0';
vmeDir_in <='0';
vmeDirN_in <='1';
blkCounter <=blkCounter +'1';
DataToMem <= vmeDataIn1 (DataWidth-1 downto 0);
addr_in <= addr_in + blkAddrInc;
WriteMem <='1';
VmeDtackN <='1';
VmeState <="1010";
if UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
else
VmeIntReqN <= (others =>'1');
end if;
when blkRd =>
dsNvectorNew <= Ds1N_in & Ds0N_in;
VmeDirFloat <='1';
vmeDir_in <='0';
vmeDirN_in <='1';
VmeDtackN <='1';
ReadMem <='0';
VmeState <= "0101";
if UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
else
VmeIntReqN <= (others =>'1');
end if;
when NextRd =>
dsNvectorOld <=dsNvectorNew;
VmeDirFloat <='1';
vmeDir_in <='0';
vmeDirN_in <='1';
addr_in <= addr_in + blkAddrInc;
blkCounter <=blkCounter +'1';
ReadMem <= '1';
VMEstate <= "0110";
if UserIntReqN ='0' and InterruptEn='1' then
VmeIntReqN <= convMyIntLevel;
else
VmeIntReqN <= (others =>'1');
end if;
when others =>
VmeDirFloat <='1';
moduleSelected <='0';
vmeDtackN<='1';
ReadMem <='0';
vmeDir_in <='0';
vmeDirN_in <='1';
intForMe <='0';
IntProcessed <='0';
WriteMem <='0';
--DataToMem <=(others =>'0');
daisy <='0';
VmeDataOut <=(others =>'0');
VMEstate <= (others =>'0');
VmeIntReqN <= (others =>'1');
end case;
end if;
end if;
end process outputs;
end Vme_intfce;
--***************************************************************************
-----------------------------------------------------------------------------
-------------- VmePackage.vhdl ----------------------------------------------
-----------------------------------------------------------------------------
--***************************************************************************
-----------------------------------------------------------------------------
------------------------------------------
------------------------------------------
-- Date : Wed Apr 10 15:07:29 2002
--
-- Author : David Dominguez
--
-- Company : CERN
--
-- Description : MTG constants and parameters
--
------------------------------------------
------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
package vme is
------------------------
-- START VME INTERFACE
--
------------------------
-- selects the interrupt number the VME module
-- answer when VmeIackNA cycle is going on
subtype VmeAddressType is std_logic_vector(23 downto 1);
subtype VmeDataType is std_logic_vector(31 downto 0);
subtype ModuleAddrType is std_logic_vector(7 downto 0);
subtype ModuleAddrLType is std_logic_vector(23 downto 23 + ModuleAddrType'right - ModuleAddrType'left);--(23 downto 16);
subtype SlaveAddrOutType is std_logic_vector(ModuleAddrLType'right - 1 downto 1);--(15 downto 1);
subtype IntAddrOutType is std_logic_vector(SlaveAddrOutType'left downto 0);--(15 downto 0);
subtype VmeAddresModType is std_logic_vector(4 downto 0);
subtype VmeIntLevelType is std_logic_vector(2 downto 0);
constant MODULE_ADDRESS_C : ModuleAddrLType := X"C6";--(23 => '1', 22 => '1', others => '0');
constant module_am : VmeAddresModType := "11101";
constant ZEROVMEADDRESS : VmeAddressType := (others => '0');
constant ONEVMEADDRESS : VmeAddressType := (ZEROVMEADDRESS'right => '1', others => '0');
constant STDNONPRIVPROGACC : VmeAddresModType := "11101";
type VmeCellType is
record
Address : VmeAddressType;
Data : VmeDataType;
Am : VmeAddresModType;
end record VmeCellType;
type VmeAddAmType is
record
Address : VmeAddressType;
Am : VmeAddresModType;
end record VmeAddAmType;
type IntAddDataType is
record
Address : integer;
Data : VmeDataType;
end record IntAddDataType;
type VmeBusOutRecord is
record
-- clk : std_logic;
VmeAddrA : VmeAddressType; -- Top level entity for the GPS2TIM module
--
-- This module receive the GPS ppsclk and 1 Mhz + the Date and Time in RS232
-- and send the corresponding Timing Frame.
--
-- PN and BMT le 21 Fevrier 2002
--
-- Version 1.0
VmeAsNA : std_logic;
VmeAmA : VmeAddresModType;
VmeDs1NA : std_logic;
VmeDs0NA : std_logic;
VmeLwordNA: std_logic;
VmeWriteNA : std_logic;
VmeIackNA : std_logic;
IackInNA : std_logic;
-- ModuleAddr : std_logic_vector(4 downto 0);
-- DataFromMemValid : std_logic;
-- DataFromMem: VmeDataType;
-- data_writen_valid : std_logic;
-- ResetNA : std_logic;
-- UserIntReqN : std_logic;
-- UserBlocks : std_logic;
VmeData : VmeDataType;
writeFinished : boolean;
readFinished : boolean;
takeControl : boolean;
ProcessOnControl : integer;
end record VmeBusOutRecord;
type VmeBusOutRecordArray is array (natural range <>) of VmeBusOutRecord;
type VmeBusInRecord is
record
VmeData : VmeDataType;
VmeDir : std_logic;
VmeBufOeN : std_logic;
IackOutNA: std_logic;
VmeAsNA : std_logic;
VmeIntReqN : std_logic_vector(7 downto 0);
dtack_n : std_logic;
end record VmeBusInRecord;
--type StdLogVecArray is array (natural range <>) of Std_logic_vector;
-- Interrupt vector to be put on data bus during
-- the VME interrupt cycle
function PullUpStdLogVec(input1, input2 : Std_logic_vector) return Std_logic_vector;
function PullUpStdLog(input1, input2 : Std_logic) return Std_logic ;
function PullUpVmeBusOut(inputs : VmeBusOutRecordArray) return VmeBusOutRecord;
--function PullUpStdLog (inputs : std_logic_vector) return
end;
package body vme is
function PullUpStdLogVec(input1, input2 : Std_logic_vector) return Std_logic_vector is
variable vStdLogVec : Std_logic_vector(31 downto 0);
begin
vStdLogVec := (others => 'U');
for M in input2'range loop
case input2(M) is
when 'U' |'X' | 'W' => if input1(M) = '0' or input1(M) = 'L' then
vStdLogVec(M) := '0';
end if;
-- when 'X' => vStdLog := 'U';
when '0' => vStdLogVec(M) := '0';
when '1' => vStdLogVec(M) := input1(M);
when 'Z' => vStdLogVec(M) := input1(M);
-- when 'W' => vStdLogVec(M) := 'U';
when 'L' => vStdLogVec(M) := '0';
when 'H' => vStdLogVec(M) := input1(M);
when others => null;
end case;
end loop;
return vStdLogVec(input2'range);
end;
function PullUpStdLog(input1, input2 : Std_logic) return Std_logic is
variable vStdLog : Std_logic;
begin
vStdLog := 'U';
case input2 is
when 'U' |'X' | 'W' => if input1 = '0' or input1 = 'L' then
vStdLog := '0';
end if;
-- when 'X' => vStdLog := 'U';
when '0' => vStdLog := '0';
when '1' => vStdLog := input1;
when 'Z' => vStdLog := input1;
-- when 'W' => vStdLog := 'U';
when 'L' => vStdLog := '0';
when 'H' => vStdLog := input1;
-- when '-' => vStdLog := 'U';
when others => null;
end case;
return vStdLog;
end;
function PullUpVmeBusOut(inputs : VmeBusOutRecordArray) return VmeBusOutRecord is
variable vVmeBusOut : VmeBusOutRecord;
begin
vVmeBusOut.VmeAddrA := (others => '1');
vVmeBusOut.VmeAsNA := '1';
vVmeBusOut.VmeAmA := (others => '1');
vVmeBusOut.VmeDs1NA := '1';
vVmeBusOut.VmeDs0NA := '1';
vVmeBusOut.VmeLwordNA:= '1';
vVmeBusOut.VmeWriteNA := '1';
vVmeBusOut.VmeIackNA := '1';
vVmeBusOut.IackInNA := '1';
vVmeBusOut.VmeData := (others => 'Z');
vVmeBusOut.writeFinished := false;
vVmeBusOut.readFinished := false;
vVmeBusOut.ProcessOnControl := -1;
for I in inputs'range loop
if inputs(I).takeControl then
vVmeBusOut.VmeAddrA := inputs(I).VmeAddrA;
vVmeBusOut.VmeAsNA := inputs(I).VmeAsNA ;
vVmeBusOut.VmeAmA := inputs(I).VmeAmA;
vVmeBusOut.VmeDs1NA := inputs(I).VmeDs1NA ;
vVmeBusOut.VmeDs0NA := inputs(I).VmeDs0NA ;
vVmeBusOut.VmeLwordNA:= inputs(I).VmeLwordNA;
vVmeBusOut.VmeWriteNA := inputs(I).VmeWriteNA ;
vVmeBusOut.VmeIackNA := inputs(I).VmeIackNA ;
vVmeBusOut.IackInNA := inputs(I).IackInNA ;
vVmeBusOut.VmeData := inputs(I).VmeData ;
vVmeBusOut.writeFinished := inputs(I).writeFinished;
vVmeBusOut.readFinished := inputs(I).readFinished;
vVmeBusOut.ProcessOnControl := I;
end if;
end loop;
return vVmeBusOut;
end;
end;
--***************************************************************************
-----------------------------------------------------------------------------
-------------- VmeSimPackage.vhdl ----------------------------------------------
-----------------------------------------------------------------------------
--***************************************************************************
-----------------------------------------------------------------------------
------------------------------------------
------------------------------------------
-- Date : Wed Apr 10 15:07:29 2002
--
-- Author : Pablo Alvarez
--
-- Company : CERN
--
-- Description : VME procedures
--
------------------------------------------
------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.vme.all;
package vmesim is
function stdvec_to_str(inp: std_logic_vector) return string;
constant INTHANDLERPOS : integer := 0;
constant SLAVEPOS : integer := 1;
procedure InitVME(
-- signal clk : in std_logic;
-- signal ResetNA : out std_logic;
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord
-- signal VmeSlaveIn : out VmeSlaveInRecord
);
procedure TreatInterruptVme(
-- signal clk : in std_logic;
-- signal ResetNA : out std_logic;
-- variable VIntLevel : in VmeIntLevelType;
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord
-- signal VmeSlaveIn : out VmeSlaveInRecord
);
procedure GenerateInterruptVme(
signal clk : in std_logic;
signal GenInterr : out std_logic;
signal InterrDone : in std_logic
);
function FindInterrupt(
signal IrqN : in std_logic_vector) return integer;
procedure ReadVME (
constant VVmeCell : VmeCellType;
variable VResult : out VmeCellType;
signal VmeBusIn : in VmeBusInRecord;
-- signal VmeSlaveOut : in VmeSlaveOutRecord;
signal VmeBusOut : out VmeBusOutRecord);
-- signal VmeSlaveIn : out VmeSlaveInRecord);
procedure ReadVME (
variable VVmeAddAm : in VmeAddAmType;
variable VResult : out VmeCellType;
-- signal VmeSlaveOut : in VmeSlaveOutRecord;
signal VmeBusIn : in VmeBusInRecord;
-- signal VmeSlaveIn : out VmeSlaveInRecord;
signal VmeBusOut : out VmeBusOutRecord);
procedure WriteVME (
variable VVmeCell : in VmeCellType;
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord);
procedure SetAddress(variable VIntAddData: in IntAddDataType;
variable VVmeCell : out VmeCellType);
procedure SetAddressC(constant VIntAdd : in integer;
variable VVmeAddAm : out VmeAddAmType);
procedure SetAddressV(variable VIntAdd : in integer;
variable VVmeAddAm : out VmeAddAmType);
procedure ReadVMEC (
constant VIntAdd : in integer;
variable VResult : out VmeCellType;
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord);
procedure ReadVMEV (
variable VIntAdd : in integer;
variable VResult : out VmeCellType;
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord);
procedure ReadVME (
variable VIntAddData : in IntAddDataType;
variable VResult : out VmeCellType;
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord);
procedure WriteVMEC (
constant VIntAdd: in integer;
variable VData : in VmeDataType;
-- variable VResult : out VmeCellType;
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord);
procedure WriteVMEV (
variable VIntAdd: in integer;
variable VData : in VmeDataType;
-- variable VResult : out VmeCellType;
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord);
------------------------
-- END VME INTERFACE
--
------------------------
end;
package body vmesim is
function stdvec_to_str(inp: std_logic_vector) return string is
variable temp: string(inp'left+1 downto 1) := (others => 'X');
begin
for i in inp'reverse_range loop
if (inp(i) = '1') then
temp(i+1) := '1';
elsif (inp(i) = '0') then
temp(i+1) := '0';
end if;
end loop;
return temp;
end function stdvec_to_str;
---------------------------------------------------------------------------
---------------------------------------------------------------------------
---------------------------------------------------------------------------
procedure InitVME(
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord
) is
begin
VmeBusOut.VmeAddrA <= (others =>'1');
VmeBusOut.VmeAsNA <='1';
VmeBusOut.IackInNA<= '1';
VmeBusOut.VmeIackNA<= '1';
VmeBusOut.VmeWriteNA <='1';
VmeBusOut.VmeDs0NA <='1';
VmeBusOut.VmeDs1NA <='1';
VmeBusOut.VmeData<= (others =>'Z');
VmeBusOut.VmeLwordNA<='1';
VmeBusOut.VmeAmA <= (others => '1');
end;
---------------------------------------------------------------------------
---------------------------------------------------------------------------
---------------------------------------------------------------------------
function FindInterrupt(
signal IrqN : in std_logic_vector) return integer is
variable vLevel : integer;
begin
vLevel := -1;
L1:for I in IrqN'range loop
if IrqN(I) = '0' then
vLevel := I;
exit L1;
end if;
end loop;
return vLevel;
end;
---------------------------------------------------------------------------
---------------------------------------------------------------------------
procedure TreatInterruptVme(
-- signal clk : in std_logic;
-- signal ResetNA : out std_logic;
-- variable VIntLevel : in VmeIntLevelType;
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord
-- signal VmeSlaveIn : out VmeSlaveInRecord
) is
variable interruptLevel : integer;
begin
VmeBusOut.takeControl <= false;
if FindInterrupt(VmeBusIn.VmeIntReqN) = -1 then
wait until FindInterrupt(VmeBusIn.VmeIntReqN) /= -1;
end if;
interruptLevel := FindInterrupt(VmeBusIn.VmeIntReqN);
if VmeBusIn.VmeAsNA /= '1' then
wait until VmeBusIn.VmeAsNA = '1';
end if;
VmeBusOut.takeControl <= true;
VmeBusOut.IackInNA <= '1';
VmeBusOut.VmeIackNA <= '1';
wait for 20 ns; -- cut and paste of the read code
--in the simulation file after an
VmeBusOut.VmeAddrA <= (others => '0');
VmeBusOut.VmeAddrA(VmeIntLevelType'left + VmeBusOut.VmeAddrA'right downto VmeBusOut.VmeAddrA'right) <= CONV_STD_LOGIC_VECTOR(interruptLevel, VmeIntLevelType'length);
VmeBusOut.VmeAmA <= STDNONPRIVPROGACC;
VmeBusOut.VmeAsNA <='0'; -- int cycle
VmeBusOut.VmeDs0NA <='0';
VmeBusOut.VmeDs1NA<='0';
VmeBusOut.VmeLwordNA<='0';
VmeBusOut.IackInNA <= '0';
VmeBusOut.VmeIackNA <= '0';
wait until VmeBusIn.dtack_n='0';
VmeBusOut.VmeAddrA <= (others => '1');
VmeBusOut.VmeAddrA(VmeIntLevelType'left + VmeBusOut.VmeAddrA'right downto VmeBusOut.VmeAddrA'right) <= (others => '1');
VmeBusOut.VmeAmA <= (others => '1');
VmeBusOut.VmeAsNA <='1'; -- int cycle
VmeBusOut.VmeDs0NA <='1';
VmeBusOut.VmeDs1NA<='1';
VmeBusOut.VmeLwordNA<='1';
VmeBusOut.takeControl <= false;
VmeBusOut.IackInNA <= '1';
VmeBusOut.VmeIackNA <= '1';
wait until VmeBusIn.dtack_n='1';
report "Interrupt vector: "&stdvec_to_str(VmeBusIn.VmeData) severity Note;
end;
---------------------------------------------------------------------------
---------------------------------------------------------------------------
---------------------------------------------------------------------------
procedure GenerateInterruptVme(
signal clk : in std_logic;
signal GenInterr : out std_logic;
signal InterrDone : in std_logic
) is
variable vInterrDuration : time;
begin
wait until falling_edge(clk);
GenInterr <= '0';
vInterrDuration := now;
wait until falling_edge(InterrDone);
GenInterr <= '1';
vInterrDuration := now - vInterrDuration;
report "Interrupt finished. Interrupt duration: " & Time'image(vInterrDuration) severity Note;
end;
---------------------------------------------------------------------------
---------------------------------------------------------------------------
---------------------------------------------------------------------------
procedure ReadVME (
constant VVmeCell : VmeCellType;
variable VResult : out VmeCellType;
signal VmeBusIn : in VmeBusInRecord;
-- signal VmeSlaveOut : in VmeSlaveOutRecord;
signal VmeBusOut : out VmeBusOutRecord
-- signal VmeSlaveIn : out VmeSlaveInRecord
) is
--<class>: signal | variable | constant
--<mode>: in | inout | out
--variable vVmeBusOut : VmeBusOutRecord;
variable ti : time;
variable doloop : boolean;
begin
--VmeSlaveIn.DataFromMemValid <= '0';
--VmeSlaveIn.DataFromMem<= (others => 'U');
-----------
-- start Read cycle
-----------
VmeBusOut.takeControl <= false;
if VmeBusIn.dtack_n /='1' then
wait until VmeBusIn.dtack_n='1';
end if;
VmeBusOut.takeControl <= true;
VmeBusOut.readFinished <=false;
VmeBusOut.VmeIackNA <= '1'; -- to prevent intack if we do
wait for 20 ns; -- cut and paste of the read code
--in the simulation file after an
VmeBusOut.VmeAddrA <= VVmeCell.Address;
VmeBusOut.VmeAmA <= VVmeCell.Am;
VmeBusOut.VmeAsNA <='0'; -- int cycle
VmeBusOut.VmeDs0NA <='0';
VmeBusOut.VmeDs1NA<='0';
VmeBusOut.VmeLwordNA<='0';
--waiting_memo<= true;
ti := now;
doloop := true;
while doloop loop
wait for 25ns;
if VmeBusIn.dtack_n = '0' then
doloop := false;
end if;
if (now > (ti + 4 us)) then
doloop := false;
end if;
end loop;
--wait until ((VmeBusIn.dtack_n = '0') or (now > (ti + 10 us)));
wait for 25 ns;
VResult.Data := VmeBusIn.VmeData;
VResult.Address := VVmeCell.Address;
assert (VVmeCell.Data = VmeBusIn.VmeData)
report "VmeData differ from expected data" severity Error;
--waiting_memo<= false;
wait for 10 ns;
VmeBusOut.VmeAsNA <='1';
VmeBusOut.takeControl <= false;
wait for 10 ns;
VmeBusOut.VmeDs0NA <='1';
VmeBusOut.VmeDs1NA <='1';
VmeBusOut.VmeLwordNA<='1';
VmeBusOut.VmeAddrA <=(others =>'1');
VmeBusOut.VmeAmA <= (others =>'1');
VmeBusOut.VmeData <=(others=>'1');
wait for 10 ns;
VmeBusOut.readFinished <=true;
wait for 10 ns;
VmeBusOut.takeControl <= false;
VmeBusOut.readFinished <=false;
end;
---------------------------------------------------------------------------
---------------------------------------------------------------------------
---------------------------------------------------------------------------
procedure ReadVME (
variable VVmeAddAm : in VmeAddAmType;
variable VResult : out VmeCellType;
signal VmeBusIn : in VmeBusInRecord;
-- signal VmeSlaveIn : out VmeSlaveInRecord;
signal VmeBusOut : out VmeBusOutRecord) is
--<class>: signal | variable | constant
--<mode>: in | inout | out
--variable vVmeBusOut : VmeBusOutRecord;
variable ti : time;
variable doloop : boolean;
begin
-----------
-- start Read cycle
-----------
--VmeSlaveIn.DataFromMemValid <= '0';
--VmeSlaveIn.DataFromMem<= (others => 'U');
VmeBusOut.takeControl <= false;
if VmeBusIn.dtack_n /='1' then
wait until VmeBusIn.dtack_n='1';
end if;
VmeBusOut.takeControl <= true;
VmeBusOut.readFinished <=false;
VmeBusOut.VmeIackNA <= '1'; -- to prevent intack if we do
wait for 20 ns; -- cut and paste of the read code
--in the simulation file after an
VmeBusOut.VmeAddrA <= VVmeAddAm.Address;
VmeBusOut.VmeAmA <= VVmeAddAm.Am;
VmeBusOut.VmeAsNA <='0'; -- int cycle
VmeBusOut.VmeDs0NA <='0';
VmeBusOut.VmeDs1NA<='0';
VmeBusOut.VmeLwordNA<='0';
report "antes del wait unitl read_mem";
--wait until VmeSlaveOut.ReadMem= '1';
--waiting_memo<= true;
--report "despues del wait unitl read_mem";
--VmeSlaveIn.DataFromMemValid <= '1';
--VmeSlaveIn.DataFromMem<= X"00110033";
ti := now;
doloop := true;
while doloop loop
wait for 25ns;
if VmeBusIn.dtack_n = '0' then
doloop := false;
end if;
if (now > (ti + 4 us)) then
doloop := false;
end if;
end loop;
--waiting_memo<= false;
wait for 10 ns;
VResult.Data := VmeBusIn.VmeData;
VResult.Address := VVmeAddAm.Address;
VResult.Am := VVmeAddAm.Am;
VmeBusOut.VmeAsNA <='1';
VmeBusOut.takeControl <= false;
wait for 10 ns;
VmeBusOut.VmeDs0NA <='1';
VmeBusOut.VmeDs1NA <='1';
VmeBusOut.VmeLwordNA<='1';
--VmeBusOut.VmeAddrA <=(others =>'Z');
--VmeBusOut.VmeData <=(others=>'Z');
wait for 10 ns;
VmeBusOut.readFinished <=true;
wait for 10 ns;
VmeBusOut.readFinished <=false;
end;
---------------------------------------------------------------------------
---------------------------------------------------------------------------
---------------------------------------------------------------------------
procedure WriteVME (
variable VVmeCell : in VmeCellType;
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord) is
--<class>: signal | variable | constant
--<mode>: in | inout | out
--variable vVmeBusOut : VmeBusOutRecord;
variable ti : time;
variable doloop : boolean;
begin
-----------
-- start Write cycle
-----------
VmeBusOut.takeControl <= false;
if VmeBusIn.dtack_n /='1' then
wait until VmeBusIn.dtack_n='1';
end if;
VmeBusOut.takeControl <= true;
VmeBusOut.writeFinished <=false;
VmeBusOut.VmeAsNA <='1'; --initialisation
VmeBusOut.IackInNA<= '1';
VmeBusOut.VmeWriteNA <='1';
VmeBusOut.VmeDs0NA <='1';
VmeBusOut.VmeDs1NA <='1';
VmeBusOut.VmeLwordNA<='1';
VmeBusOut.VmeIackNA <= '1'; -- to prevent intack if we do
wait for 20 ns; -- cut and paste of the read code
--in the simulation file after an
-- int cycle
VmeBusOut.VmeAddrA<= VVmeCell.Address;
VmeBusOut.VmeAmA <= VVmeCell.Am;
VmeBusOut.VmeWriteNA <='0';
wait for 20 ns;
VmeBusOut.VmeAsNA <='0';
VmeBusOut.VmeData <= VVmeCell.Data;
VmeBusOut.VmeDs0NA <='0';
VmeBusOut.VmeDs1NA<='0';
VmeBusOut.VmeLwordNA<='0';
ti := now;
doloop := true;
while doloop loop
wait for 25ns;
if VmeBusIn.dtack_n = '0' then
doloop := false;
end if;
if (now > (ti + 4 us)) then
doloop := false;
end if;
end loop;
wait for 5 ns;
VmeBusOut.takeControl <= true;
VmeBusOut.VmeAsNA <='1';
VmeBusOut.VmeWriteNA <='1';
VmeBusOut.VmeData <=(others =>'Z');
VmeBusOut.VmeAddrA<= (others =>'1');
VmeBusOut.VmeAmA <= (others =>'1');
wait for 20 ns;
VmeBusOut.VmeDs1NA <='1';
VmeBusOut.VmeDs0NA <='1';
VmeBusOut.VmeLwordNA<='1';
wait for 10 ns;
VmeBusOut.writeFinished <=true;
wait for 10 ns;
VmeBusOut.takeControl <= false;
VmeBusOut.writeFinished <=false;
-----------
-- END Write cycle
-----------
end;
-----------------------------------------------------------------
-----------------------------------------------------------------
-----------------------------------------------------------------
procedure SetAddress(variable VIntAddData: in IntAddDataType;
variable VVmeCell : out VmeCellType) is
begin
vVmeCell.Address(MODULE_ADDRESS_C'range) := MODULE_ADDRESS_C;
vVmeCell.Address(SlaveAddrOutType'range) := CONV_STD_LOGIC_VECTOR(VIntAddData.Address,MODULE_ADDRESS_C'right - 1);
vVmeCell.Am := STDNONPRIVPROGACC;
vVmeCell.Data := VIntAddData.Data;
end;
-----------------------------------------------------------------
-----------------------------------------------------------------
-----------------------------------------------------------------
procedure SetAddressC(constant VIntAdd : in integer;
variable VVmeAddAm : out VmeAddAmType) is
begin
VVmeAddAm.Address(MODULE_ADDRESS_C'range) := MODULE_ADDRESS_C;
VVmeAddAm.Address(SlaveAddrOutType'range) := CONV_STD_LOGIC_VECTOR(VIntAdd,MODULE_ADDRESS_C'right - 1);
VVmeAddAm.Am := STDNONPRIVPROGACC;
end;
-----------------------------------------------------------------
-----------------------------------------------------------------
-----------------------------------------------------------------
procedure SetAddressV(variable VIntAdd : in integer;
variable VVmeAddAm : out VmeAddAmType) is
begin
VVmeAddAm.Address(MODULE_ADDRESS_C'range) := MODULE_ADDRESS_C;
VVmeAddAm.Address(SlaveAddrOutType'range) := CONV_STD_LOGIC_VECTOR(VIntAdd,MODULE_ADDRESS_C'right - 1);
VVmeAddAm.Am := STDNONPRIVPROGACC;
end;
-----------------------------------------------------------------
-----------------------------------------------------------------
-----------------------------------------------------------------
procedure ReadVMEC (
constant VIntAdd : in integer;
variable VResult : out VmeCellType;
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord) is
variable vVmeAddAm : VmeAddAmType;
begin
SetAddressC(VIntAdd => VIntAdd, VVmeAddAm => vVmeAddAm);
ReadVME (VVmeAddAm => vVmeAddAm, VResult => VResult,
VmeBusIn => VmeBusIn, VmeBusOut => VmeBusOut);
end;
-----------------------------------------------------------------
-----------------------------------------------------------------
-----------------------------------------------------------------
procedure ReadVMEV (
variable VIntAdd : in integer;
variable VResult : out VmeCellType;
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord) is
variable vVmeAddAm : VmeAddAmType;
begin
SetAddressV(VIntAdd => VIntAdd, VVmeAddAm => vVmeAddAm);
ReadVME (VVmeAddAm => vVmeAddAm, VResult => VResult,
VmeBusIn => VmeBusIn, VmeBusOut => VmeBusOut);
end;
-----------------------------------------------------------------
-----------------------------------------------------------------
-----------------------------------------------------------------
procedure ReadVME (
variable VIntAddData : in IntAddDataType;
variable VResult : out VmeCellType;
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord) is
variable vVmeCell : VmeCellType;
begin
SetAddress(VIntAddData => VIntAddData, VVmeCell =>vVmeCell);
ReadVME (VVmeCell => vVmeCell, VResult => VResult,
VmeBusIn => VmeBusIn, VmeBusOut => VmeBusOut);
end;
-----------------------------------------------------------------
-----------------------------------------------------------------
-----------------------------------------------------------------
procedure WriteVMEC (
constant VIntAdd: in integer;
variable VData : in VmeDataType;
-- variable VResult : out VmeCellType;
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord) is
variable vVmeCell : VmeCellType;
variable vIntAddData : IntAddDataType;
begin
vIntAddData.Address := VIntAdd;
vIntAddData.Data := VData;
SetAddress(VIntAddData => vIntAddData, VVmeCell =>vVmeCell);
WriteVME (VVmeCell => vVmeCell, VmeBusIn => VmeBusIn, VmeBusOut => VmeBusOut);
end;
procedure WriteVMEV (
variable VIntAdd: in integer;
variable VData : in VmeDataType;
-- variable VResult : out VmeCellType;
signal VmeBusIn : in VmeBusInRecord;
signal VmeBusOut : out VmeBusOutRecord) is
variable vVmeCell : VmeCellType;
variable vIntAddData : IntAddDataType;
begin
vIntAddData.Address := VIntAdd;
vIntAddData.Data := VData;
SetAddress(VIntAddData => vIntAddData, VVmeCell =>vVmeCell);
WriteVME (VVmeCell => vVmeCell, VmeBusIn => VmeBusIn, VmeBusOut => VmeBusOut);
end;
end vmesim;
module ga_decoder(GA, BAR);
input[4:0] GA;
output[7:0] BAR;
wire[4:0] GA;
reg[7:0] BAR;
always @(GA)
begin
case(GA)
5'h1E: BAR <= 8'h08; //SLOT 1
5'h1D: BAR <= 8'h10; //SLOT 2
5'h1C: BAR <= 8'h18; //SLOT 3
5'h1B: BAR <= 8'h20; //SLOT 4
5'h1A: BAR <= 8'h28; //SLOT 5
5'h19: BAR <= 8'h30; //SLOT 6
5'h18: BAR <= 8'h38; //SLOT 7
5'h17: BAR <= 8'h40; //SLOT 8
5'h16: BAR <= 8'h48; //SLOT 9
5'h15: BAR <= 8'h50; //SLOT 10
5'h14: BAR <= 8'h58; //SLOT 11
5'h13: BAR <= 8'h60; //SLOT 12
5'h12: BAR <= 8'h68; //SLOT 13
5'h11: BAR <= 8'h70; //SLOT 14
5'h10: BAR <= 8'h78; //SLOT 15
5'h0F: BAR <= 8'h80; //SLOT 16
5'h0E: BAR <= 8'h88; //SLOT 17
5'h0D: BAR <= 8'h90; //SLOT 18
5'h0C: BAR <= 8'h98; //SLOT 19
5'h0B: BAR <= 8'hA0; //SLOT 20
5'h0A: BAR <= 8'hA8; //SLOT 21
endcase
end
endmodule
`timescale 1 ns / 1 ps
module glbl ();
wire GR;
wire GSR;
wire GTS;
wire PRLD;
endmodule
module loc_bus(CLOCK, RESETn, ADDRBUS, DATA_BUS, DTACKn, VME_R_Wn, LOC_CS, LOC_R_Wn, LHOLD, LHOLDA, LAD_BUS, ADSn, LW_Rn, READYn, LOCAL_BUS_IN);
input CLOCK, RESETn, DTACKn, VME_R_Wn, LOC_CS, LOC_R_Wn, LHOLDA, READYn;
input[31:0] ADDRBUS;
inout[31:0] DATA_BUS, LAD_BUS;
output LHOLD, ADSn, LW_Rn;
output[31:0] LOCAL_BUS_IN;
wire CLOCK, RESETn, DTACKn, VME_R_Wn, LOC_CS, LOC_R_Wn, LHOLDA, READYn;
wire LHOLD, ADSn, LW_Rn, read;
wire[31:0] ADDRBUS, DATA_BUS, LAD_BUS, INT_BUS, LOCAL_BUS_IN;
reg[6:0] state, next_state;
reg[31:0] data_bus_reg;
parameter L_IDLE = 0, //0000
L_ADS_R = 1, //0003
L_ADS_W = 2, //0005
L_READ = 3, //0009
L_WRITE = 4, //0011
L_END = 5, //0021
L_ILLEGAL = 6; //0041
assign LAD_BUS = (state[L_READ]) ? 32'hz : INT_BUS; //high selects left
assign INT_BUS = ((~state[L_IDLE]) | (state[L_ADS_R]) | (state[L_ADS_W])) ? ADDRBUS : DATA_BUS; //high selects left
assign ADSn = ~((state[L_ADS_R]) | (state[L_ADS_W]));
assign LW_Rn = ~((state[L_ADS_R]) | (state[L_READ]));
assign LHOLD = 1'b1;
//assign DATA_BUS = (LOC_CS & ~DTACKn & VME_R_Wn) ? data_bus_reg : 32'bz ; //high selects left
assign read = (~LW_Rn & ~READYn);
assign LOCAL_BUS_IN = data_bus_reg;
always @(posedge read or negedge RESETn)
begin
if (~RESETn) data_bus_reg <= 32'b0;
else if (read) data_bus_reg <= LAD_BUS;
end
/*********************************************************/
// STATE MACHINE
/*********************************************************/
always @(LHOLDA or LOC_CS or LOC_R_Wn or READYn or state)
begin
next_state = 6'b00_0001;
case(1'b1)
~state[L_IDLE]: //00
begin
if (LHOLDA & LOC_CS & LOC_R_Wn) next_state[L_ADS_R] = 1'b1;
else if (LHOLDA & LOC_CS & ~LOC_R_Wn) next_state[L_ADS_W] = 1'b1;
else next_state[L_IDLE] = 1'b0;
end
state[L_ADS_R]: //03
begin
next_state[L_READ] = 1'b1;
end
state[L_ADS_W]: //05
begin
next_state[L_WRITE] = 1'b1;
end
state[L_READ]: //09
begin
if(~READYn) next_state[L_END] = 1'b1;
else next_state[L_READ] = 1'b1;
end
state[L_WRITE]: //11
begin
if(~READYn) next_state[L_END] = 1'b1;
else next_state[L_WRITE] = 1'b1;
end
state[L_END]: //21
begin
if(~LOC_CS) next_state[L_IDLE] = 1'b0;
else next_state[L_END] = 1'b1;
end
default: //41
begin
next_state[L_ILLEGAL] = 1'b1;
end
endcase
end
// build the state flip-flops
always @(posedge CLOCK or negedge RESETn)
begin
if (~RESETn)
begin
state <= #1 7'b000_0000;
end
else
state <= #1 next_state;
end
endmodule
/*
task access_local_bus;
input write_lbus;
input[31:0] address, data_in;
begin
//wait(~lhold)
//wait(~lholda)
lw_r <= #10 1'b1;
dt_r <= #10 1'b1;
data_reg = data_in;
address_reg = address;
begin
@(posedge clk)
begin
lhold <= #10 1'b1;
data_from_fec <= #10 32'bx;
end
wait(lholda)
@(posedge clk)
begin
adsz <= #10 1'b0;
if(~write_lbus) begin
lw_r <= #10 1'b0;
dt_r <= #10 1'b0;
end
end
@(posedge clk);
begin
adsz <= #10 1'b1;
d_en <= #10 1'b0;
end
wait(~readyz)
begin
blastz <= #10 1'b0;
end
@(posedge clk)
begin
blastz <= #10 1'b1;
if(~write_lbus) data_from_fec <= #10 lad_bus;
end
@(posedge clk)
begin
lw_r <= #10 1'b1;
lhold <= #10 1'b1;
d_en <= #10 1'b1;
dt_r <= #10 1'b1;
end
@(posedge clk);
end
end
endtask
*/
module mpx_10(sel, din0, din1, din2, din3, din4, din5, din6, din7, din8, din9, dout);
input[3:0] sel;
input[7:0] din0, din1, din2, din3, din4, din5, din6, din7, din8, din9;
output[7:0] dout;
wire[3:0] sel;
wire[7:0] din0, din1, din2, din3, din4;
wire[7:0] din5, din6, din7, din8, din9, dout;
reg[7:0] mpx_out;
assign dout = mpx_out;
always @(sel or din9 or din8 or din7 or din6 or din5 or din4 or din3 or din2 or din1 or din0)
begin : read_mux
case (sel)
4'b1111: mpx_out <= #1 din0;
4'b1110: mpx_out <= #1 din1;
4'b1101: mpx_out <= #1 din2;
4'b1100: mpx_out <= #1 din3;
4'b1011: mpx_out <= #1 din4;
4'b1010: mpx_out <= #1 din5;
4'b1001: mpx_out <= #1 din6;
4'b1000: mpx_out <= #1 din7;
4'b0111: mpx_out <= #1 din8;
4'b0110: mpx_out <= #1 din9;
default: mpx_out <= #1 8'hFF;
endcase
end
endmodule
module mpx_4(sel, din0, din1, din2, din3, dout);
input[1:0] sel;
input[7:0] din0, din1, din2, din3;
output[7:0] dout;
wire[1:0] sel;
wire[7:0] din0, din1, din2, din3, din4;
wire[7:0] din5, din6, din7, din8, din9, dout;
reg[7:0] mpx_out;
assign dout = mpx_out;
always @(sel or din3 or din2 or din1 or din0)
begin : read_mux
case (sel)
2'b11: mpx_out <= #1 din0;
2'b10: mpx_out <= #1 din1;
2'b01: mpx_out <= #1 din2;
2'b00: mpx_out <= #1 din3;
default: mpx_out <= #1 8'hFF;
endcase
end
endmodule
scope -set test_fixt
scope -set test_fixt.vme_xil_top1
scope -set test_fixt.vme_xil_top1.vme_slave1
database -open waves -into waves.shm -default
probe -create -shm test_fixt.vme_xil_top1.vme_slave1.ACK_CYCLE test_fixt.vme_xil_top1.vme_slave1.ADDRBUS test_fixt.vme_xil_top1.vme_slave1.BAR test_fixt.vme_xil_top1.vme_slave1.BERRn test_fixt.vme_xil_top1.vme_slave1.C_ROM test_fixt.vme_xil_top1.vme_slave1.CLOCK test_fixt.vme_xil_top1.vme_slave1.CR_SPACE test_fixt.vme_xil_top1.vme_slave1.DATA_BUS test_fixt.vme_xil_top1.vme_slave1.DS0n test_fixt.vme_xil_top1.vme_slave1.DS1n test_fixt.vme_xil_top1.vme_slave1.DTACKn test_fixt.vme_xil_top1.vme_slave1.IRQ1n test_fixt.vme_xil_top1.vme_slave1.LOC_CS test_fixt.vme_xil_top1.vme_slave1.LOC_DS0n test_fixt.vme_xil_top1.vme_slave1.LOC_DS1n test_fixt.vme_xil_top1.vme_slave1.LOC_R_Wn test_fixt.vme_xil_top1.vme_slave1.LOCAL_BUS_IN test_fixt.vme_xil_top1.vme_slave1.LWORDn test_fixt.vme_xil_top1.vme_slave1.RESETn test_fixt.vme_xil_top1.vme_slave1.ROM_DATA test_fixt.vme_xil_top1.vme_slave1.VME_AM test_fixt.vme_xil_top1.vme_slave1.VME_ASn test_fixt.vme_xil_top1.vme_slave1.VME_BUF_DIR test_fixt.vme_xil_top1.vme_slave1.VME_BUF_OE test_fixt.vme_xil_top1.vme_slave1.VME_R_Wn
run
exit
ncxlmode: v2.2.(s19): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc.
ncxlmode: v2.2.(s19): Started on Jun 10, 2003 at 15:53:14
ncxlmode
-f
vme.vc
+ncsimargs+"-gui"
+debug
+ncaccess+wc
ncxlmode: *W,OPTNOS: Option (+caxl) not supported in ncxlmode.
ncxlmode: *W,BADPRF: The +debug option may have an adverse performance impact.
ncsim> source /vlsicad/micsoft/LDV22/tools/inca/files/ncsimrc
ncsim> scope -set test_fixt
ncsim> scope -set test_fixt.vme_xil_top1
ncsim> scope -set test_fixt.vme_xil_top1.vme_slave1
ncsim> database -open waves -into waves.shm -default
Created default SHM database waves
ncsim> probe -create -shm test_fixt.vme_xil_top1.vme_slave1.ACK_CYCLE test_fixt.vme_xil_top1.vme_slave1.ADDRBUS test_fixt.vme_xil_top1.vme_slave1.BAR test_fixt.vme_xil_top1.vme_slave1.BERRn test_fixt.vme_xil_top1.vme_slave1.C_ROM test_fixt.vme_xil_top1.vme_slave1.CLOCK test_fixt.vme_xil_top1.vme_slave1.CR_SPACE test_fixt.vme_xil_top1.vme_slave1.DATA_BUS test_fixt.vme_xil_top1.vme_slave1.DS0n test_fixt.vme_xil_top1.vme_slave1.DS1n test_fixt.vme_xil_top1.vme_slave1.DTACKn test_fixt.vme_xil_top1.vme_slave1.IRQ1n test_fixt.vme_xil_top1.vme_slave1.LOC_CS test_fixt.vme_xil_top1.vme_slave1.LOC_DS0n test_fixt.vme_xil_top1.vme_slave1.LOC_DS1n test_fixt.vme_xil_top1.vme_slave1.LOC_R_Wn test_fixt.vme_xil_top1.vme_slave1.LOCAL_BUS_IN test_fixt.vme_xil_top1.vme_slave1.LWORDn test_fixt.vme_xil_top1.vme_slave1.RESETn test_fixt.vme_xil_top1.vme_slave1.ROM_DATA test_fixt.vme_xil_top1.vme_slave1.VME_AM test_fixt.vme_xil_top1.vme_slave1.VME_ASn test_fixt.vme_xil_top1.vme_slave1.VME_BUF_DIR test_fixt.vme_xil_top1.vme_slave1.VME_BUF_OE test_fixt.vme_xil_top1.vme_slave1.VME_R_Wn
Created probe 1
ncsim> run
Simulation stopped via $stop(1) at time 21828 NS + 1
ncsim> exit
ncxlmode: v2.2.(s19): Exiting on Jun 10, 2003 at 15:53:58 (total: 00:00:44)
`include "glbl.v"
`timescale 1ns /1ps
module test_fixt();
wire DTACKn, BERRn, IRQ1n, LOC_R_Wn, LOC_CS, LOC_DS1n, LOC_DS0n;
wire C_ROM, VME_BUF_DIR, VME_BUF_OE, LHOLD, ADSn, LW_Rn;
tri[31:0] DATA_BUS, LAD_BUS;
reg CLOCK, RESETn, VME_ASn, VME_R_Wn, DS0n, DS1n, LWORDn, ACK_CYCLE, IACKn;
reg LHOLDA, READYn;
reg[4:0] GA;
reg[5:0] VME_AM;
reg[7:0] LINTIn;
reg[31:0] ADDRBUS, data_from_vme, address_reg, data_reg;
integer vme_address;
parameter READ = 1'b1,
WRITE = 1'b0;
parameter FUNC0_0 = 19'h7FF63,
FUNC0_1 = 19'h7FF67,
FUNC0_2 = 19'h7FF6B,
FUNC0_3 = 19'h7FF6F;
initial
begin
`ifdef xilinx
$sdf_annotate( `xilinx, vme_test_fixt.vme_xil_top1,,,, );
`endif
CLOCK <= 1'b0;
RESETn <= 1'b0;
VME_ASn <= 1'b1;
VME_R_Wn <= 1'b1;
DS0n <= 1'b1;
DS1n <= 1'b1;
LWORDn <= 1'b1;
ACK_CYCLE <= 1'b0;
IACKn <= 1'b1;
READYn <= 1'b0;
LHOLDA <= 1'b1;
LINTIn <= 8'hFF;
GA <= 5'h1C; // slot 3
VME_AM <= 6'h2F;
ADDRBUS <= 32'h00_18_00_50;
repeat(5) @(posedge CLOCK);
RESETn <= 1'b1;
repeat(10) @(posedge CLOCK);
wait (DTACKn);
@(posedge CLOCK) VME_ASn <= 1'b0;
wait (~DTACKn);
@(posedge DTACKn) #5 VME_ASn <= 1'b1;
ADDRBUS <= 32'h00_1F_FC_50;
repeat(10) @(posedge CLOCK);
wait (DTACKn);
@(posedge CLOCK) VME_ASn <= 1'b0;
wait (~DTACKn);
@(posedge DTACKn) #5 VME_ASn <= 1'b1;
repeat(10) @(posedge CLOCK);
vme_address <= 32'h00_1F_FC_00;
@(posedge CLOCK);
repeat(10)
begin
vme_access(READ, vme_address, 32'hz, 6'h2F);
vme_address <= vme_address + 4;
repeat(10) @(posedge CLOCK);
end
vme_address <= 32'h00_18_00_00;
@(posedge CLOCK);
repeat(10)
begin
vme_access(READ, vme_address, 32'hz, 6'h2F);
vme_address <= vme_address + 4;
repeat(10) @(posedge CLOCK);
end
//write
vme_access(WRITE, {11'b0,2'b11,FUNC0_0}, 32'h00000055, 6'h2F);
repeat(10) @(posedge CLOCK);
vme_access(WRITE, 32'h55000004, 32'h00000055, 6'h09);
repeat(10) @(posedge CLOCK);
vme_access(READ, 32'h55000008, 32'hz, 6'h09);
repeat(100) @(posedge CLOCK);
$stop;
end
assign DATA_BUS = (~VME_R_Wn) ? data_reg : 32'hz ; //high selects left
always #12 CLOCK <= ~CLOCK;
vme_xil_top vme_xil_top1(
.CLOCK(CLOCK),
.RESETn(RESETn),
.ADDRBUS(ADDRBUS),
.VME_AM(VME_AM),
.VME_ASn(VME_ASn),
.VME_R_Wn(VME_R_Wn),
.DS0n(DS0n),
.DS1n(DS1n),
.LWORDn(LWORDn),
.GA(GA),
.ACK_CYCLE(ACK_CYCLE),
.DATA_BUS(DATA_BUS),
.DTACKn(DTACKn),
.BERRn(BERRn),
.IRQ1n(IRQ1n),
.LOC_R_Wn(LOC_R_Wn),
.LOC_CS(LOC_CS),
.LOC_DS1n(LOC_DS1n),
.LOC_DS0n(LOC_DS0n),
.C_ROM(C_ROM),
.VME_BUF_DIR(VME_BUF_DIR),
.VME_BUF_OE(VME_BUF_OE),
.LHOLD(LHOLD),
.LHOLDA(LHOLDA),
.LAD_BUS(LAD_BUS),
.ADSn(ADSn),
.LW_Rn(LW_Rn),
.READYn(READYn),
.LINTIn(LINTIn)
);
task vme_access;
input read;
input[31:0] address, data_in;
input[5:0] am;
begin
data_reg = data_in;
address_reg = address;
ADDRBUS <= address_reg;
VME_AM <= am;
LWORDn <= 1'b1;
IACKn <= 1'b1;
#35 VME_ASn <= 1'b0;
if(~read) VME_R_Wn <= 1'b0;
wait (DTACKn & ~BERRn);
DS0n <= 1'b0;
DS1n <= 1'b0;
wait (~DTACKn);
if (read) data_from_vme <= DATA_BUS;
#40 VME_ASn <= 1'b1;
DS0n <= 1'b1;
DS1n <= 1'b1;
#10 VME_R_Wn <= 1'b1;
//just to finish the cycle in Jose's slave wait wait
wait (DTACKn);
end
endtask
endmodule
+tms_incl+
+delay_mode_path
+caxl
+sxl_keep_minimum
+libext+.v+
+sdf_verbose
+sdf_nocheck_celltype
+neg_tchk
+gui_sync
//+notimingchecks
test_fixt.v
vme_xil_top.v
vme_slave.v
vme_mem.v
ga_decoder.v
loc_bus.v
mpx_4.v
mpx_10.v
-y /homedir/ljuslin/fec/verilog/fec_xilinx/XilinxCoreLib
module vme_rom(addr, clk, dout, sinit);
input clk, sinit;
input[10:0] addr;
output[7:0] dout;
wire clk, sinit;
wire[10:0] addr;
reg[7:0] dout;
reg[7:0] rom[2047:0];
initial
begin
$readmemb("/homedir/ljuslin/vme/vme_rom.mif", rom, 0);
end
always @(posedge clk or negedge sinit)
begin
if (~sinit) dout <= 8'b0;
else dout <= rom[addr];
end
endmodule
10001010
00000000
00000100
00001110
10000001
10000001
00000010
01000011
01010010
10100010
00001101
11001100
00000001
00000010
00000011
00000100
00100000
00000011
00000000
00000001
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000010
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00010000
00000011
00000000
00010000
00111111
11001100
00000000
00000000
00000000
00000000
00000000
00000000
00000000
10000100
10000100
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000010
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00001000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
11111111
00000000
00000000
00000010
11111111
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
01000100
01000011
01000011
00101101
01010100
01000101
01010011
01010100
01000101
01010010
00101101
01001100
01001001
01010000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
module vme_rom (
addr,
clk,
dout,
sinit);
input [10 : 0] addr;
input clk;
output [7 : 0] dout;
input sinit;
// synopsys translate_off
BLKMEMSP_V5_0 #(
11, // c_addr_width
"0", // c_default_data
2048, // c_depth
0, // c_enable_rlocs
0, // c_has_default_data
0, // c_has_din
0, // c_has_en
0, // c_has_limit_data_pitch
0, // c_has_nd
0, // c_has_rdy
0, // c_has_rfd
1, // c_has_sinit
0, // c_has_we
8, // c_limit_data_pitch
"vme_rom.mif", // c_mem_init_file
0, // c_pipe_stages
0, // c_reg_inputs
"0", // c_sinit_value
8, // c_width
0, // c_write_mode
"0", // c_ybottom_addr
1, // c_yclk_is_rising
1, // c_yen_is_high
"hierarchy1", // c_yhierarchy
0, // c_ymake_bmm
"4kx1", // c_yprimitive_type
1, // c_ysinit_is_high
"1024", // c_ytop_addr
0, // c_yuse_single_primitive
1) // c_ywe_is_high
inst (
.ADDR(addr),
.CLK(clk),
.DOUT(dout),
.SINIT(sinit),
.DIN(),
.EN(),
.ND(),
.RFD(),
.RDY(),
.WE());
// synopsys translate_on
endmodule
//-- Most inputs are the VME lines, direct connetcion, or trough buffers...
//-- ACK_CYCLE = vme cycle acknoledge, used to finish the VME data cycle, starts the counter delay for the DTACK generation!
//-- CROM- clock of the ROM used only in configuration read cycles...
//-- IRQ1n is not used
//-- BERRn is not used
module vme_slave (CLOCK, RESETn, BAR, ADDRBUS,
VME_AM, VME_ASn, VME_R_Wn, DS0n, DS1n, LWORDn , ACK_CYCLE, ROM_DATA, DATA_BUS,
DTACKn, BERRn, IRQ1n, LOC_R_Wn, LOC_CS, LOC_DS1n, LOC_DS0n, CR_SPACE, C_ROM, VME_BUF_DIR , VME_BUF_OE,
LOCAL_BUS_IN
);
input CLOCK, RESETn, VME_ASn, VME_R_Wn, DS0n, DS1n, LWORDn , ACK_CYCLE;
input[5:0] VME_AM;
input[7:0] BAR, ROM_DATA;
input[31:0] ADDRBUS, LOCAL_BUS_IN;
inout[31:0] DATA_BUS;
output DTACKn, BERRn, IRQ1n, LOC_R_Wn, LOC_CS, LOC_DS1n;
output LOC_DS0n, C_ROM, VME_BUF_DIR , VME_BUF_OE;
output[10:0] CR_SPACE;
wire CLOCK, RESETn, VME_ASn, VME_R_Wn, DS0n, DS1n, LWORDn , ACK_CYCLE;
wire[5:0] VME_AM;
wire[7:0] BAR, ROM_DATA, INT_BUS;
wire[7:0] CR_CSR, CSR_BUS, UDB, FUNC7, FUNC6, FUNC5, FUNC4, FUNC3, FUNC2, FUNC1, FUNC0;
wire[31:0] ADDRBUS, DATA_BUS, INTBUS_TRI, LOCAL_BUS_IN, LOCAL_BUS;
wire DTACKn, BERRn, IRQ1n, LOC_R_Wn, LOC_CS, LOC_DS1n, CARD_SEL_DLY_START;
wire LOC_DS0n, C_ROM_clk, CSR_READ, CSR_WRITE, CLR_ADD, READ;
wire BIT_SET_EN, BIT_CLR_EN, CRAM_OWNER_REG_EN, UD_BIT_SET_REG_EN, UD_BIT_CLR_REG_EN;
wire FUNC7_ADER_EN3, FUNC7_ADER_EN2, FUNC7_ADER_EN1, FUNC7_ADER_EN0;
wire FUNC6_ADER_EN3, FUNC6_ADER_EN2, FUNC6_ADER_EN1, FUNC6_ADER_EN0;
wire FUNC5_ADER_EN3, FUNC5_ADER_EN2, FUNC5_ADER_EN1, FUNC5_ADER_EN0;
wire FUNC4_ADER_EN3, FUNC4_ADER_EN2, FUNC4_ADER_EN1, FUNC4_ADER_EN0;
wire FUNC3_ADER_EN3, FUNC3_ADER_EN2, FUNC3_ADER_EN1, FUNC3_ADER_EN0;
wire FUNC2_ADER_EN3, FUNC2_ADER_EN2, FUNC2_ADER_EN1, FUNC2_ADER_EN0;
wire FUNC1_ADER_EN3, FUNC1_ADER_EN2, FUNC1_ADER_EN1, FUNC1_ADER_EN0;
wire FUNC0_ADER_EN3, FUNC0_ADER_EN2, FUNC0_ADER_EN1, FUNC0_ADER_EN0;
wire CARD_SEL_DLY_9, CARDSEL, CONF_ACCESS, CR, CSR;
reg CLOCK_DIV, C_ROM;
reg FUNC0_SEL0, FUNC1_SEL0, FUNC2_SEL0, FUNC3_SEL0, FUNC4_SEL0, FUNC5_SEL0, FUNC6_SEL0, FUNC7_SEL0;
reg FUNC0_SEL1, FUNC1_SEL1, FUNC2_SEL1, FUNC3_SEL1, FUNC4_SEL1, FUNC5_SEL1, FUNC6_SEL1, FUNC7_SEL1;
reg FUNC0_SEL2, FUNC1_SEL2, FUNC2_SEL2, FUNC3_SEL2, FUNC4_SEL2, FUNC5_SEL2, FUNC6_SEL2, FUNC7_SEL2;
reg FUNC0_SEL3, FUNC1_SEL3, FUNC2_SEL3, FUNC3_SEL3, FUNC4_SEL3, FUNC5_SEL3, FUNC6_SEL3, FUNC7_SEL3;
reg BAR_SEL, BIT_C_SEL, BIT_S_SEL, UDBS_SEL, UDBC_SEL, CRAM_SEL;
reg VME_BUF_DIR , VME_BUF_OE, DEC_A0, VME_AS_REG, VME_AS_REG0;
reg[5:0] V_AM;
reg[7:0] BIT_SET_REG, BIT_CLR_REG, CRAM_OWNER_REG, UD_BIT_SET_REG, UD_BIT_CLR_REG;
reg[10:0] CR_SPACE;
reg[11:0] CARD_SEL_DLY;
reg[18:0] CSR_SPACE;
reg[31:0] V_ADD;
reg[31:0] FUNC7_ADER, FUNC6_ADER, FUNC5_ADER, FUNC4_ADER, FUNC3_ADER, FUNC2_ADER, FUNC1_ADER, FUNC0_ADER;
assign READ = (VME_R_Wn & CONF_ACCESS) | (VME_R_Wn & CARDSEL);
assign DATA_BUS = (READ) ? LOCAL_BUS : 32'hz ; //high selects left
assign INT_BUS = (CSR_READ) ? CSR_BUS : ROM_DATA; //high selects left
assign LOCAL_BUS = (LOC_R_Wn) ? LOCAL_BUS_IN : {24'b0, INT_BUS}; //high selects left
//assign INTBUS_TRI = {24'b0, DATA_BUS[7:0]};
//-----------------------------------------------------------------------------------
//--- VME TO LOCAL BUS INTERFACE DEFINITIONS
//-----------------------------------------------------------------------------------
assign CSR_WRITE = (~VME_R_Wn & CSR & CONF_ACCESS);
//CSR write signal, allows write of the CSR registers
assign CSR_READ = (VME_R_Wn & CSR & CONF_ACCESS);
//CSR Read signal, allows read of the CSR Registers
assign CLR_ADD = (~RESETn | (CARD_SEL_DLY[10] & ~CARD_SEL_DLY[11])); //shorted by adding ~[11]
//CLEAR VME ADDRESS AND AM REGISTERS ...after sending DTACK card_sel_dly[10] arrives
//some clocks later to end the access to the board, clears regsiters and "close" buffers
assign LOC_DS1n = (DS1n & CARDSEL);
assign LOC_DS0n = (DS0n & CARDSEL);
assign LOC_R_Wn = (VME_R_Wn & CARDSEL);
//Local Rwad Write signal active when card is selected only...
assign LOC_CS = CARDSEL;
assign BERRn = 1'b0;
assign IRQ1n = 1'b0;
assign DTACKn = !CARD_SEL_DLY[2];
//--dtack duration (from CARD_SEL_DLY[2] to CARD_SEL_DLY[9] in this case)
//-- IMPORTANT: depending of the logic used externally remove or not the inversion ("!") or the CARD_SEL_DLY[2] signal !
//--------------------------------------------------------------
//-- COMPARE VME_ADD AND VME_AM
//--------------------------------------------------------------
//--BIDIR BUS (LOC_DATA AND VMEDATA)
//-- only implemented a one byte access to the CR and CSR regions
//-- databus[31:8] is implemented for future changes_need.
//DATA_BUS = INTBUS_TRI.out;
//INTBUS_TRI[31:8]= 1'b0;
//INTBUS_TRI[31:8].oe= 1'b0;
//----------------------------------
// synchronisation of VME_ASn
always @(posedge CLOCK or negedge RESETn)
begin
if (~RESETn) VME_AS_REG0 <= 1'b0;
else VME_AS_REG0 <= ~VME_ASn;
end
always @(posedge CLOCK or negedge RESETn)
begin
if (~RESETn) VME_AS_REG <= 1'b0;
else VME_AS_REG <= VME_AS_REG0;
end
//----------------------------------
always @(negedge VME_ASn or posedge CLR_ADD)
begin
if (CLR_ADD) V_ADD[31:0] <= 32'b1;
else V_ADD[31:0] <= ADDRBUS[31:0];
end
always @(negedge VME_ASn or posedge CLR_ADD)
begin
if (CLR_ADD) V_AM[5:0] <= 6'b1;
else V_AM[5:0] <= VME_AM[5:0];
end
//---------------------------------------------------
//--- DTACK DELAY and LOCAL_CS Generator
//---------------------------------------------------
//-- simply a delay counter to send and finish DTACK signal
//--started with some conditions that each user must define
assign CARD_SEL_DLY_9 = ((CARD_SEL_DLY[9] & ~CARD_SEL_DLY[10])| ~RESETn); //shorted by adding ~[10]
assign CARD_SEL_DLY_START = ( ((CARDSEL | CR | CSR) & VME_AS_REG) | ACK_CYCLE);
//-- this are the conditions to finish the Cycle
//-- user can add conditons ..
//-- CARDSEL automaticaly ends the "data" vme cycle if the board is accessed.
//-- CR or CSR ends the configuration cycles
//-- ACK_Cycle is the external signal to end the signal, can be "and" with card_sel...
//-- use of "or CR or CSR" in this condition is mandatory
always @(posedge CLOCK or negedge RESETn)
begin
if (~RESETn) CLOCK_DIV <= 1'b0;
else CLOCK_DIV <= ~CLOCK_DIV;
end
/*
always @(posedge CARD_SEL_DLY_START or posedge CARD_SEL_DLY_9)
begin
if(CARD_SEL_DLY_9) CARD_SEL_DLY[0] <= 1'b0;
else CARD_SEL_DLY[0] <= 1'b1;
end
*/
always @(posedge CLOCK_DIV or posedge CARD_SEL_DLY_9)
begin
if(CARD_SEL_DLY_9) CARD_SEL_DLY[0] <= 1'b0;
else if(CARD_SEL_DLY_START) CARD_SEL_DLY[0] <= 1'b1;
end
always @(posedge CLOCK_DIV or posedge CARD_SEL_DLY_9)
begin
if(CARD_SEL_DLY_9) CARD_SEL_DLY[1] <= 1'b0;
else CARD_SEL_DLY[1] <= CARD_SEL_DLY[0];
end
always @(posedge CLOCK_DIV or posedge CARD_SEL_DLY_9)
begin
if(CARD_SEL_DLY_9) CARD_SEL_DLY[2] <= 1'b0;
else CARD_SEL_DLY[2] <= CARD_SEL_DLY[1];
end
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if(~RESETn) CARD_SEL_DLY[3] <= 1'b0;
else CARD_SEL_DLY[3] <= CARD_SEL_DLY[2];
end
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if(~RESETn) CARD_SEL_DLY[4] <= 1'b0;
else CARD_SEL_DLY[4] <= CARD_SEL_DLY[3];
end
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if(~RESETn) CARD_SEL_DLY[5] <= 1'b0;
else CARD_SEL_DLY[5] <= CARD_SEL_DLY[4];
end
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if(~RESETn) CARD_SEL_DLY[6] <= 1'b0;
else CARD_SEL_DLY[6] <= CARD_SEL_DLY[5];
end
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if(~RESETn) CARD_SEL_DLY[7] <= 1'b0;
else CARD_SEL_DLY[7] <= CARD_SEL_DLY[6];
end
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if(~RESETn) CARD_SEL_DLY[8] <= 1'b0;
else CARD_SEL_DLY[8] <= CARD_SEL_DLY[7];
end
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if(~RESETn) CARD_SEL_DLY[9] <= 1'b0;
else CARD_SEL_DLY[9] <= CARD_SEL_DLY[8];
end
//-- end of DTACKn and clear of delay counters
//-- user can extend the DTACK adding more registers to the CARD_SEL_DLY...
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if(~RESETn) CARD_SEL_DLY[10] <= 1'b0;
else CARD_SEL_DLY[10] <= CARD_SEL_DLY[9];
end
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if(~RESETn) CARD_SEL_DLY[11] <= 1'b0;
else CARD_SEL_DLY[11] <= CARD_SEL_DLY[10];
end
//-----------------------------------------------------------
//-- LOCAL BUS BUFFERS CONTROL AND SELECTION
//-----------------------------------------------------------
//--There are 2 lines for data the vme data bus drivers control..
//-- users can use any kind of drivers, and care to change the "default"
//-- state of these lines prior to test the VME access
always @(VME_R_Wn or CARDSEL or CONF_ACCESS)
begin
if (!VME_R_Wn & (CARDSEL | CONF_ACCESS))
begin
VME_BUF_DIR <= 1'b1; //VME BUS DRIVERS = VME -> LOCAL BUS
VME_BUF_OE <= 1'b0;
end
else if(VME_R_Wn & (CARDSEL | CONF_ACCESS))
begin
VME_BUF_DIR <= 1'b0; //VME BUS DRIVERS = LOCAL BUS -> VME
VME_BUF_OE <= 1'b0;
end
else
begin
VME_BUF_DIR <= 1'b0; //VME BUS DRIVERS OFF
VME_BUF_OE <= 1'b1;
end
end
//-----------------------------------------------------------
//-- CR_CSR SPACE ADDRESS DECODE REGION
//-----------------------------------------------------------
//-- address decoder for the CR or CSR space
//-- not much to say...
//-- compares the VME address with the crate position and the AM
//-- and selects from the Address region "18..0" if is an access to the CR or to the CSR"
//-- VME ADDRESS [0] is added here.
assign CONF_ACCESS = ((V_ADD[23:19] == BAR[7:3]) & (V_AM[5:0] == 6'h2F) );
assign CSR = (CONF_ACCESS & (V_ADD[18:0] >= 19'h7FC00));
assign CR = (CONF_ACCESS & (V_ADD[18:0] < 19'h7FC00));
always @(CR or V_ADD)
begin
if (CR) CR_SPACE[10:0] <= V_ADD[12:2]; //CR ADDRESS (READ CYCLES ONLY)
else CR_SPACE[10:0] <= 11'b0;
end
always @(CSR or V_ADD)
begin
if (CSR) CSR_SPACE[18:0] <= {V_ADD[18:1], 1'b1}; // CSR ADDRESS
else CSR_SPACE[18:0] <= 19'b0;
end
assign C_ROM_clk = (CR & VME_R_Wn & CONF_ACCESS & CARD_SEL_DLY[2]);
always @(posedge C_ROM_clk or posedge CLR_ADD)
begin
if(CLR_ADD) C_ROM <= 1'b0;
else C_ROM <= 1'b1;
end
//CSR.clk = CLOCK;
//-- condition to access the CR_ROM :
//-- cr decoded, read access, conf_access (just a protection) and DTACK started : data is placed on bus
//-- to the CPU to get it...
//-- the MAIN address compare (base address of the board and it's access mode as refered on the VME ROM)...
//-- check the ROM definitions for address bit compare and address modifier in use...
//-- 2 examples of the same baord...
//--------------------------------------------------------------------------------
//--1st MAIN ADDRESS COMPARE. select the compare mask (FUNC0_ADER[31 to 24])
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//-- 2nd MAIN ADDRESS COMPARE. select the compare mask (FUNC1_ADER[31 to 24])
//--------------------------------------------------------------------------------
assign CARDSEL = ( (FUNC0_ADER[31:24] == V_ADD[31:24]) & (V_AM[5:0] == 6'h09) & ~CONF_ACCESS) |
((FUNC1_ADER[31:24] == V_ADD[31:24]) & (V_AM[5:0] == 6'h0B) & ~CONF_ACCESS);
mpx_4 CR_CSR_MPX(
.sel(CSR_SPACE[3:2]),
.din0(BAR[7:0]),
.din1(BIT_SET_REG[7:0]),
.din2(BIT_CLR_REG[7:0]),
.din3(CRAM_OWNER_REG[7:0]),
.dout(CR_CSR)
);
mpx_4 UDB_MPX(
.sel(CSR_SPACE[3:2]),
.din0(UD_BIT_SET_REG[7:0]),
.din1(UD_BIT_CLR_REG[7:0]),
.din2(8'b0),
.din3(8'b0),
.dout(UDB)
);
mpx_4 FUNC_7(
.sel(CSR_SPACE[3:2]),
.din0(FUNC7_ADER[7:0]),
.din1(FUNC7_ADER[15:8]),
.din2(FUNC7_ADER[23:16]),
.din3(FUNC7_ADER[31:24]),
.dout(FUNC7)
);
mpx_4 FUNC_6(
.sel(CSR_SPACE[3:2]),
.din0(FUNC6_ADER[7:0]),
.din1(FUNC6_ADER[15:8]),
.din2(FUNC6_ADER[23:16]),
.din3(FUNC6_ADER[31:24]),
.dout(FUNC6)
);
mpx_4 FUNC_5(
.sel(CSR_SPACE[3:2]),
.din0(FUNC5_ADER[7:0]),
.din1(FUNC5_ADER[15:8]),
.din2(FUNC5_ADER[23:16]),
.din3(FUNC5_ADER[31:24]),
.dout(FUNC5)
);
mpx_4 FUNC_4(
.sel(CSR_SPACE[3:2]),
.din0(FUNC4_ADER[7:0]),
.din1(FUNC4_ADER[15:8]),
.din2(FUNC4_ADER[23:16]),
.din3(FUNC4_ADER[31:24]),
.dout(FUNC4)
);
mpx_4 FUNC_3(
.sel(CSR_SPACE[3:2]),
.din0(FUNC3_ADER[7:0]),
.din1(FUNC3_ADER[15:8]),
.din2(FUNC3_ADER[23:16]),
.din3(FUNC3_ADER[31:24]),
.dout(FUNC3)
);
mpx_4 FUNC_2(
.sel(CSR_SPACE[3:2]),
.din0(FUNC2_ADER[7:0]),
.din1(FUNC2_ADER[15:8]),
.din2(FUNC2_ADER[23:16]),
.din3(FUNC2_ADER[31:24]),
.dout(FUNC2)
);
mpx_4 FUNC_1(
.sel(CSR_SPACE[3:2]),
.din0(FUNC1_ADER[7:0]),
.din1(FUNC1_ADER[15:8]),
.din2(FUNC1_ADER[23:16]),
.din3(FUNC1_ADER[31:24]),
.dout(FUNC1)
);
mpx_4 FUNC_0(
.sel(CSR_SPACE[3:2]),
.din0(FUNC0_ADER[7:0]),
.din1(FUNC0_ADER[15:8]),
.din2(FUNC0_ADER[23:16]),
.din3(FUNC0_ADER[31:24]),
.dout(FUNC0)
);
mpx_10 FUNC(
.sel(CSR_SPACE[7:4]),
.din0(CR_CSR),
.din1(UDB),
.din2(FUNC7),
.din3(FUNC6),
.din4(FUNC5),
.din5(FUNC4),
.din6(FUNC3),
.din7(FUNC2),
.din8(FUNC1),
.din9(FUNC0),
.dout(CSR_BUS[7:0])
);
always @(CSR_SPACE)
begin
case(CSR_SPACE[18:0])
19'h7FFFF: BAR_SEL <= 1'b1; //-- CR_CSR BAR READ VALUE
19'h7FFFB: BIT_S_SEL <= 1'b1; //-- BIT SET REGISTER WRITE
19'h7FFF7: BIT_C_SEL <= 1'b1; //-- BIT CLEAR REGISTER WRITE
19'h7FFF3: CRAM_SEL <= 1'b1; //-- CONFIGURATION RAM ACESS -- OPTIONAL WRITE
19'h7FFEF: UDBS_SEL <= 1'b1; //-- OPTIONAL
19'h7FFEB: UDBC_SEL <= 1'b1; //-- OPTIONAL
//-- MANDATORY, MAIN ADDRESS TO COMPARE, ADER7
19'h7FFDF: FUNC7_SEL3 <= 1'b1;
19'h7FFDB: FUNC7_SEL2 <= 1'b1;
19'h7FFD7: FUNC7_SEL1 <= 1'b1;
19'h7FFD3: FUNC7_SEL0 <= 1'b1;
//-- MANDATORY, MAIN ADDRESS TO COMPARE, ADER6
19'h7FFCF: FUNC6_SEL3 <= 1'b1;
19'h7FFCB: FUNC6_SEL2 <= 1'b1;
19'h7FFC7: FUNC6_SEL1 <= 1'b1;
19'h7FFC3: FUNC6_SEL0 <= 1'b1;
//-- MANDATORY, MAIN ADDRESS TO COMPARE, ADER5
19'h7FFBF: FUNC5_SEL3 <= 1'b1;
19'h7FFBB: FUNC5_SEL2 <= 1'b1;
19'h7FFB7: FUNC5_SEL1 <= 1'b1;
19'h7FFB3: FUNC5_SEL0 <= 1'b1;
//-- MANDATORY, MAIN ADDRESS TO COMPARE, ADER4
19'h7FFAF: FUNC4_SEL3 <= 1'b1;
19'h7FFAB: FUNC4_SEL2 <= 1'b1;
19'h7FFA7: FUNC4_SEL1 <= 1'b1;
19'h7FFA3: FUNC4_SEL0 <= 1'b1;
//-- MANDATORY, MAIN ADDRESS TO COMPARE, ADER3
19'h7FF9F: FUNC3_SEL3 <= 1'b1;
19'h7FF9B: FUNC3_SEL2 <= 1'b1;
19'h7FF97: FUNC3_SEL1 <= 1'b1;
19'h7FF93: FUNC3_SEL0 <= 1'b1;
//-- MANDATORY, MAIN ADDRESS TO COMPARE, ADER2
19'h7FF8F: FUNC2_SEL3 <= 1'b1;
19'h7FF8B: FUNC2_SEL2 <= 1'b1;
19'h7FF87: FUNC2_SEL1 <= 1'b1;
19'h7FF83: FUNC2_SEL0 <= 1'b1;
//-- MANDATORY, MAIN ADDRESS TO COMPARE, ADER1
19'h7FF7F: FUNC1_SEL3 <= 1'b1;
19'h7FF7B: FUNC1_SEL2 <= 1'b1;
19'h7FF77: FUNC1_SEL1 <= 1'b1;
19'h7FF73: FUNC1_SEL0 <= 1'b1;
//-- MANDATORY, MAIN ADDRESS TO COMPARE, ADER0
19'h7FF6F: FUNC0_SEL3 <= 1'b1;
19'h7FF6B: FUNC0_SEL2 <= 1'b1;
19'h7FF67: FUNC0_SEL1 <= 1'b1;
19'h7FF63: FUNC0_SEL0 <= 1'b1;
default:
begin
BAR_SEL <= 1'b0;
BIT_S_SEL<= 1'b0;
BIT_C_SEL<= 1'b0;
CRAM_SEL <= 1'b0;
UDBS_SEL <= 1'b0;
UDBC_SEL <= 1'b0;
FUNC0_SEL0 <= 1'b0;
FUNC1_SEL0 <= 1'b0;
FUNC2_SEL0 <= 1'b0;
FUNC3_SEL0 <= 1'b0;
FUNC4_SEL0 <= 1'b0;
FUNC5_SEL0 <= 1'b0;
FUNC6_SEL0 <= 1'b0;
FUNC7_SEL0 <= 1'b0;
FUNC0_SEL1 <= 1'b0;
FUNC1_SEL1 <= 1'b0;
FUNC2_SEL1 <= 1'b0;
FUNC3_SEL1 <= 1'b0;
FUNC4_SEL1 <= 1'b0;
FUNC5_SEL1 <= 1'b0;
FUNC6_SEL1 <= 1'b0;
FUNC7_SEL1 <= 1'b0;
FUNC0_SEL2 <= 1'b0;
FUNC1_SEL2 <= 1'b0;
FUNC2_SEL2 <= 1'b0;
FUNC3_SEL2 <= 1'b0;
FUNC4_SEL2 <= 1'b0;
FUNC5_SEL2 <= 1'b0;
FUNC6_SEL2 <= 1'b0;
FUNC7_SEL2 <= 1'b0;
FUNC0_SEL3 <= 1'b0;
FUNC1_SEL3 <= 1'b0;
FUNC2_SEL3 <= 1'b0;
FUNC3_SEL3 <= 1'b0;
FUNC4_SEL3 <= 1'b0;
FUNC5_SEL3 <= 1'b0;
FUNC6_SEL3 <= 1'b0;
FUNC7_SEL3 <= 1'b0;
end
endcase
end
//-----------------------------------------------------------------
//---- REGISTERS
//-----------------------------------------------------------------
assign FUNC7_ADER_EN3 = (CSR_WRITE & !DS0n & FUNC7_SEL3);
assign FUNC7_ADER_EN2 = (CSR_WRITE & !DS0n & FUNC7_SEL2);
assign FUNC7_ADER_EN1 = (CSR_WRITE & !DS0n & FUNC7_SEL1);
assign FUNC7_ADER_EN0 = (CSR_WRITE & !DS0n & FUNC7_SEL0);
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if (~RESETn) FUNC7_ADER[31:0] <= 32'b0;
else if(FUNC7_ADER_EN3) FUNC7_ADER[7:0] <= DATA_BUS[7:0];
else if(FUNC7_ADER_EN2) FUNC7_ADER[15:8] <= DATA_BUS[7:0];
else if(FUNC7_ADER_EN1) FUNC7_ADER[23:16] <= DATA_BUS[7:0];
else if(FUNC7_ADER_EN0) FUNC7_ADER[31:24] <= DATA_BUS[7:0];
end
assign FUNC6_ADER_EN3 = (CSR_WRITE & !DS0n & FUNC6_SEL3);
assign FUNC6_ADER_EN2 = (CSR_WRITE & !DS0n & FUNC6_SEL2);
assign FUNC6_ADER_EN1 = (CSR_WRITE & !DS0n & FUNC6_SEL1);
assign FUNC6_ADER_EN0 = (CSR_WRITE & !DS0n & FUNC6_SEL0);
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if (~RESETn) FUNC6_ADER[31:0] <= 32'b0;
else if(FUNC6_ADER_EN3) FUNC6_ADER[7:0] <= DATA_BUS[7:0];
else if(FUNC6_ADER_EN2) FUNC6_ADER[15:8] <= DATA_BUS[7:0];
else if(FUNC6_ADER_EN1) FUNC6_ADER[23:16] <= DATA_BUS[7:0];
else if(FUNC6_ADER_EN0) FUNC6_ADER[31:24] <= DATA_BUS[7:0];
end
assign FUNC5_ADER_EN3 = (CSR_WRITE & !DS0n & FUNC5_SEL3);
assign FUNC5_ADER_EN2 = (CSR_WRITE & !DS0n & FUNC5_SEL2);
assign FUNC5_ADER_EN1 = (CSR_WRITE & !DS0n & FUNC5_SEL1);
assign FUNC5_ADER_EN0 = (CSR_WRITE & !DS0n & FUNC5_SEL0);
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if (~RESETn) FUNC5_ADER[31:0] <= 32'b0;
else if(FUNC5_ADER_EN3) FUNC5_ADER[7:0] <= DATA_BUS[7:0];
else if(FUNC5_ADER_EN2) FUNC5_ADER[15:8] <= DATA_BUS[7:0];
else if(FUNC5_ADER_EN1) FUNC5_ADER[23:16] <= DATA_BUS[7:0];
else if(FUNC5_ADER_EN0) FUNC5_ADER[31:24] <= DATA_BUS[7:0];
end
assign FUNC4_ADER_EN3 = (CSR_WRITE & !DS0n & FUNC4_SEL3);
assign FUNC4_ADER_EN2 = (CSR_WRITE & !DS0n & FUNC4_SEL2);
assign FUNC4_ADER_EN1 = (CSR_WRITE & !DS0n & FUNC4_SEL1);
assign FUNC4_ADER_EN0 = (CSR_WRITE & !DS0n & FUNC4_SEL0);
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if (~RESETn) FUNC4_ADER[31:0] <= 32'b0;
else if(FUNC4_ADER_EN3) FUNC4_ADER[7:0] <= DATA_BUS[7:0];
else if(FUNC4_ADER_EN2) FUNC4_ADER[15:8] <= DATA_BUS[7:0];
else if(FUNC4_ADER_EN1) FUNC4_ADER[23:16] <= DATA_BUS[7:0];
else if(FUNC4_ADER_EN0) FUNC4_ADER[31:24] <= DATA_BUS[7:0];
end
assign FUNC3_ADER_EN3 = (CSR_WRITE & !DS0n & FUNC3_SEL3);
assign FUNC3_ADER_EN2 = (CSR_WRITE & !DS0n & FUNC3_SEL2);
assign FUNC3_ADER_EN1 = (CSR_WRITE & !DS0n & FUNC3_SEL1);
assign FUNC3_ADER_EN0 = (CSR_WRITE & !DS0n & FUNC3_SEL0);
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if (~RESETn) FUNC3_ADER[31:0] <= 32'b0;
else if(FUNC3_ADER_EN3) FUNC3_ADER[7:0] <= DATA_BUS[7:0];
else if(FUNC3_ADER_EN2) FUNC3_ADER[15:8] <= DATA_BUS[7:0];
else if(FUNC3_ADER_EN1) FUNC3_ADER[23:16] <= DATA_BUS[7:0];
else if(FUNC3_ADER_EN0) FUNC3_ADER[31:24] <= DATA_BUS[7:0];
end
assign FUNC2_ADER_EN3 = (CSR_WRITE & !DS0n & FUNC2_SEL3);
assign FUNC2_ADER_EN2 = (CSR_WRITE & !DS0n & FUNC2_SEL2);
assign FUNC2_ADER_EN1 = (CSR_WRITE & !DS0n & FUNC2_SEL1);
assign FUNC2_ADER_EN0 = (CSR_WRITE & !DS0n & FUNC2_SEL0);
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if (~RESETn) FUNC2_ADER[31:0] <= 32'b0;
else if(FUNC2_ADER_EN3) FUNC2_ADER[7:0] <= DATA_BUS[7:0];
else if(FUNC2_ADER_EN2) FUNC2_ADER[15:8] <= DATA_BUS[7:0];
else if(FUNC2_ADER_EN1) FUNC2_ADER[23:16] <= DATA_BUS[7:0];
else if(FUNC2_ADER_EN0) FUNC2_ADER[31:24] <= DATA_BUS[7:0];
end
assign FUNC1_ADER_EN3 = (CSR_WRITE & !DS0n & FUNC1_SEL3);
assign FUNC1_ADER_EN2 = (CSR_WRITE & !DS0n & FUNC1_SEL2);
assign FUNC1_ADER_EN1 = (CSR_WRITE & !DS0n & FUNC1_SEL1);
assign FUNC1_ADER_EN0 = (CSR_WRITE & !DS0n & FUNC1_SEL0);
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if (~RESETn) FUNC1_ADER[31:0] <= 32'b0;
else if(FUNC1_ADER_EN3) FUNC1_ADER[7:0] <= DATA_BUS[7:0];
else if(FUNC1_ADER_EN2) FUNC1_ADER[15:8] <= DATA_BUS[7:0];
else if(FUNC1_ADER_EN1) FUNC1_ADER[23:16] <= DATA_BUS[7:0];
else if(FUNC1_ADER_EN0) FUNC1_ADER[31:24] <= DATA_BUS[7:0];
end
assign FUNC0_ADER_EN3 = (CSR_WRITE & !DS0n & FUNC0_SEL3);
assign FUNC0_ADER_EN2 = (CSR_WRITE & !DS0n & FUNC0_SEL2);
assign FUNC0_ADER_EN1 = (CSR_WRITE & !DS0n & FUNC0_SEL1);
assign FUNC0_ADER_EN0 = (CSR_WRITE & !DS0n & FUNC0_SEL0);
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if (~RESETn)FUNC0_ADER[31:0] <= 32'b0;
else if(FUNC0_ADER_EN3) FUNC0_ADER[7:0] <= DATA_BUS[7:0];
else if(FUNC0_ADER_EN2) FUNC0_ADER[15:8] <= DATA_BUS[7:0];
else if(FUNC0_ADER_EN1) FUNC0_ADER[23:16] <= DATA_BUS[7:0];
else if(FUNC0_ADER_EN0) FUNC0_ADER[31:24] <= DATA_BUS[7:0];
end
assign BIT_SET_EN = (!DS0n & BIT_S_SEL);
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if (~RESETn) BIT_SET_REG[7:0] <= 8'b0;
else if(BIT_SET_EN) BIT_SET_REG[7:0] <= DATA_BUS[7:0];
end
assign BIT_CLR_EN = (!DS0n & BIT_C_SEL );
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if (~RESETn) BIT_CLR_REG[7:0] <= 8'b0;
else if(BIT_CLR_EN) BIT_CLR_REG[7:0] <= DATA_BUS[7:0];
end
assign CRAM_OWNER_REG_EN = (!DS0n & CRAM_SEL);
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if (~RESETn) CRAM_OWNER_REG[7:0] <= 8'b0;
else if(CRAM_OWNER_REG_EN) CRAM_OWNER_REG[7:0] <= DATA_BUS[7:0];
end
assign UD_BIT_SET_REG_EN = (!DS0n & UDBS_SEL);
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if (~RESETn) UD_BIT_SET_REG[7:0] <= 8'b0;
else if(UD_BIT_SET_REG_EN) UD_BIT_SET_REG[7:0] <= DATA_BUS[7:0];
end
assign UD_BIT_CLR_REG_EN = (!DS0n & UDBC_SEL);
always @(posedge CLOCK_DIV or negedge RESETn)
begin
if (~RESETn) UD_BIT_CLR_REG[7:0] <= 8'b0;
else if(UD_BIT_CLR_REG_EN) UD_BIT_CLR_REG[7:0] <= DATA_BUS[7:0];
end
endmodule
module vme_xil_top(CLOCK, RESETn, ADDRBUS,
VME_AM, VME_ASn, VME_R_Wn, DS0n, DS1n, LWORDn, GA, ACK_CYCLE, DATA_BUS,
DTACKn, BERRn, IRQ1n, LOC_R_Wn, LOC_CS, LOC_DS1n, LOC_DS0n, C_ROM, VME_BUF_DIR, VME_BUF_OE,
LHOLD, LHOLDA, LAD_BUS, ADSn, LW_Rn, READYn, LINTIn
);
input CLOCK, RESETn, VME_ASn, VME_R_Wn, DS0n, DS1n, LWORDn , ACK_CYCLE;
input READYn, LHOLDA;
input[4:0] GA;
input[5:0] VME_AM;
input[7:0] LINTIn;
input[31:0] ADDRBUS;
inout[31:0] DATA_BUS, LAD_BUS;
output DTACKn, BERRn, IRQ1n, LOC_R_Wn, LOC_CS, LOC_DS1n;
output LOC_DS0n, C_ROM, VME_BUF_DIR , VME_BUF_OE;
output LHOLD, ADSn, LW_Rn;
wire CLOCK, RESETn, VME_ASn, VME_R_Wn, DS0n, DS1n, LWORDn , ACK_CYCLE;
wire DTACKn, BERRn, IRQ1n, LOC_R_Wn, LOC_CS, LOC_DS1n;
wire LOC_DS0n, C_ROM, VME_BUF_DIR , VME_BUF_OE;
wire LHOLD, LHOLDA, ADSn, LW_Rn, READYn;
wire[4:0] GA;
wire[5:0] VME_AM;
wire[7:0] BAR, ROM_DATA, LINTIn;
wire[10:0] CR_SPACE;
wire[31:0] ADDRBUS, DATA_BUS, LOCAL_BUS_IN;
vme_slave vme_slave1(
.CLOCK(CLOCK),
.RESETn(RESETn),
.BAR(BAR[7:0]),
.ADDRBUS(ADDRBUS),
.VME_AM(VME_AM),
.VME_ASn(VME_ASn),
.VME_R_Wn(VME_R_Wn),
.DS0n(DS0n),
.DS1n(DS1n),
.LWORDn(LWORDn),
.ACK_CYCLE(ACK_CYCLE),
.ROM_DATA(ROM_DATA),
.DATA_BUS(DATA_BUS),
.DTACKn(DTACKn),
.BERRn(BERRn),
.IRQ1n(IRQ1n),
.LOC_R_Wn(LOC_R_Wn),
.LOC_CS(LOC_CS),
.LOC_DS1n(LOC_DS1n),
.LOC_DS0n(LOC_DS0n),
.CR_SPACE(CR_SPACE[10:0]),
.C_ROM(C_ROM),
.VME_BUF_DIR(VME_BUF_DIR),
.VME_BUF_OE(VME_BUF_OE),
.LOCAL_BUS_IN(LOCAL_BUS_IN)
);
loc_bus loc_bus1(
.CLOCK(CLOCK),
.RESETn(RESETn),
.ADDRBUS(ADDRBUS),
.DATA_BUS(DATA_BUS),
.DTACKn(DTACKn),
.VME_R_Wn(VME_R_Wn),
.LOC_CS(LOC_CS),
.LOC_R_Wn(VME_R_Wn),
.LHOLD(LHOLD),
.LHOLDA(LHOLDA),
.LAD_BUS(LAD_BUS),
.ADSn(ADSn),
.LW_Rn(LW_Rn),
.READYn(READYn),
.LOCAL_BUS_IN(LOCAL_BUS_IN)
);
vme_rom vme_rom1 (
.addr(CR_SPACE[10:0]),
.clk(C_ROM),
.dout(ROM_DATA),
.sinit(RESETn)
);
ga_decoder ga_decoder1(
.GA(GA),
.BAR(BAR)
);
endmodule
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment