?? config_controller.tdf
字號:
The_Address_Counter.aclr = restart_sequence;
-- JMC Changes
The_CF_RST_Counter.aclr = !CONFIG_DONE;
-- end
The_Dclk_Divider.aclr = restart_sequence;
The_Data_Bit_Counter.aclr = restart_sequence;
The_Shift_Register.aclr = restart_sequence;
d1_safe_config.clrn = RESET_n;
d2_safe_config.clrn = RESET_n;
d1_reset_source.clrn = RESET_n;
d2_reset_source.clrn = RESET_n;
cause_was_safe_config.clrn = RESET_n;
sync_config_request.clrn = RESET_n;
-- Thinking about this one gives me a headache:
The_Reset_Counter.aclr = !RESET_n;
-- JMC Changes
The_CF_Counter.aclr = !CONFIG_DONE;
The_CF_Counter.cnt_en = !The_CF_Counter.cout;
-- end
Reset_Pulse.prn = RESET_n;
----------------
-- DCLK divider
--
-- This entire little system operates at the DCLK rate,
-- which is 1/8 the master input clk (cpld_CLKOSC) rate of
-- 50MHz. This gives us ~6.25MHz clk rate.
--
-- Of course all the registers actually run off the faster
-- clk but, in the traditional style, are enabled only 1/8 of
-- the time.
--
-- The high-for-one / low-for-four DCLK clk-enable pulse comes from
-- the carry-out of a divide-by-four counter. The MSB of the counter
-- is used as DCLK (to the Cyclone chip) directly.
--
-- Note that we want to hold the FPGA's DCLK input LOW
-- unless we're actually clking-in bits, as-indicated by State_Counting.
--
dclkq3_stcntg = The_Dclk_Divider.q[3] & State_Counting.q;
-- dclk to the FPGA
dclk_en = The_Dclk_Divider.cout; -- carry
-- dclk_en to The_Data_Bit_Counter
----------------
-- Data-Bit Counter
--
-- We have to dwell on each address (data byte) for eight DCLK cycles
-- Thus, we enable the address-counter on only one out of every eight
-- DCLK cycles.
--
byte_count_en = (dclk_en & The_Data_Bit_Counter.cout);
-- clock enables the The_Address_Counter
-- Wire-up this happy clk-enable to all the other registers:
CONFIG_n_reg.ena = dclk_en;
State_Waiting_For_STATUS_n.ena = dclk_en;
State_Counting.ena = dclk_en;
State_Done.ena = dclk_en;
State_Error.ena = dclk_en;
State_JTAG_Config.ena = dclk_en;
The_Data_Bit_Counter.clk_en = dclk_en;
The_Address_Counter.clk_en = byte_count_en;
The_Shift_Register.enable = dclk_en & (State_Counting.q); -- shift: clk_enable
----------------
-- Reset-Pulse clk enable
--
-- The registers that figure-in to the reset-pulse computation
-- are enabled at a relatively low rate to give us a nice, slow,
-- wide pulse and well-debounced inputs.
-- TPA: Deal with this later.
--
d1_safe_config.ena = The_Reset_Counter.cout;
d2_safe_config.ena = The_Reset_Counter.cout;
d1_reset_source.ena = The_Reset_Counter.cout;
d2_reset_source.ena = The_Reset_Counter.cout;
----------------
-- nCONFIG output
--
-- We hold nCONFIG low to "start the entire process." When we let
-- go, the Cyclone starts thinkin'. When it's ready to receive a configuration,
-- it tells us by letting nSTATUS go high.
--
-- So, to start things rolling, we hold nCONFIG low for a while,
-- then release it (let it go high). To keep this simple,
-- I'll just hold nCONFIG low when we're in reset, then
-- release it as soon as RESET_n goes away.
--
CONFIG_n_reg.d = B"1";
---------------- --
-- The first thing we do, upon wake-up, is go into the
-- "Waiting_For_nSTATUS" state (which is uniquely signified by the
-- correspondingly-named flip-flop containing a 1). This state
-- is true until we see nSTATUS become 1, after which it
-- is never true again. We can express this concept simply thus:
--
State_Waiting_For_STATUS_n.d = !STATUS_n;
----------------
-- STATE: Counting.
--
-- This bit enables the address-counter. It's true after we see
-- nSTATUS from the Cyclone go high (which tells us it's ready). We
-- set the "Counting" bit when we see that the "Waiting_For_nSTATUS"
-- bit is false.
--
-- We keep right on a'countin' until we see CONFIG_DONE go true,
-- at which point we know, er, that the configuration process is done.
--
-- When configuration is done, the "Counting" state-bit gets set to zero.
-- The machine then moves into "Done"-mode.
--
-- Also, being in State_Error disables counting.
-- ALWAYS TRUE!
State_Counting.d = !State_Waiting_For_STATUS_n.q &
!CONFIG_DONE &
CONFIG_n_reg.q &
!State_Error.q ;
The_Address_Counter.cnt_en = State_Counting.q # try_asmi_config.q;
-- JMC Changes
The_CF_RST_Counter.cnt_en = CONFIG_DONE & !The_CF_RST_Counter.q[21];
-- end
The_Data_Bit_Counter.cnt_en = State_Counting.q # try_asmi_config.q;
-- using_flash = State_Counting.q; -- maybe to tristate flash pins?
----------------
-- STATE: Done.
--
-- You know you're done when:
--
-- * The FPGA says it's done!
-- * Gee, it sure seems like we've tried long enough.
--
-- The Cyclone chip will drive CONFIG_DONE true (1) when it's all done.
-- If we get to the end of our address-count range (256KBytes), then
-- we should stop whether the Cyclone says it's done or not. If it has
-- a problem and wants us to start over, it signals so with nSTATUS.
-- I've learned from hard experience that there's no value in continuing
-- to clk the Cyclone chip forever if it doesn't appear to be listening.
--
-- ph: clean up this comment.
--
-- State_Done.d = CONFIG_DONE # counter_wrapped.q # State_Done.q;
State_Done.d = CONFIG_DONE # State_Done.q;
-- delete "counter_wrapped" fixed error light problem
-- THIS LINE TRI-STATES ALL OUTPUTS ALWAYS (useful for debugging):
-- State_Done.d = B"1" ;
----------------
-- STATE: ACTIVE for ASMI config only
--
-- Set configuration mode on the MSEL pins
-- MSEL0 must be
-- low for EPCS config
-- high for user or safe config load from parallel flash
-- low when configured, or during JTAG config, or in Error state,
-- to enable tornado_spiblock.
pld_MSEL0 = !State_Error.q & !State_JTAG_Config.q & !State_Done.q &
(!try_asmi_config.q # cause_was_safe_config);
-- MSEL0: High (1) = Passive Serial mode,
-- Low (0) = Active Serial mode
pld_MSEL1 = B"0";
-- MSEL1: Low (0) for both Passive Serial and Active Serial modes
----------------
-- Output Control.
--
-- In general, this device wants to drive its outputs only while it is
-- in the process of configuring from flash. Put another way, this device
-- wants to "let go of" (Hi-Z) its outputs when configuring from ASMI, and
-- when configuration is done (successful), or configuration has failed.
--
-- So we want to drive the outputs whenever it's not State_Done, nor is it
-- State_Error, nor we're configuring from ASMI. One could say, "well, we
-- shouldn't be driving during/after configuration from JTAG also". I say:
-- by the time the user gets around to JTAGing in a new configuration, we'll
-- be in either State_Done or State_Error anyway.
--
-- There is one exception to the tri-stating rule:
--
-- * The nCONFIG pin is "open collector," so we want to
-- turn its output-enable ON when we want to drive nCONFIG
-- low, and OFF when we want let nCONFIG go high.
--
drive_outputs = !State_Done.q & !State_Error.q & !try_asmi_config.q;
-- Signals headin' for the outputs:
--
-- Address mapping:
--
-- We only use enough of the flash to store two configuration-images.
-- For this design, we have 8MBytes of flash, and each 1S10ES config image
-- takes a bit less than a megabyte. Thus, we use 1/4 of the flash
-- to store two images (a user image and a safe image). It is
-- polite to use the top (high) 1/4 of the flash, hence the
-- high-order address bits are set to 1.
--
-- The "user" configuration is, by convention, located in the
-- lowest (address) half of the part of the flash we're using to
-- store configuration images. Thus, when we're trying the "user"
-- configuration, we want to set this bit to zero.
--
obuf_A[].in = The_Address_Counter.q[];
obuf_flash_A22.in = B"1"; -- Use high 1/4 address-range of flash.
obuf_flash_A21.in = B"1";
obuf_flash_A20.in = !try_user_config.q; -- A20 gives low-half for
-- user image, 0x600k vs. 0x700k
obuf_flash_CS_n.in = B"0"; -- select
obuf_flash_OE_n.in = B"0"; -- enable
obuf_flash_RW_n.in = B"1"; -- read only
obuf_DCLK.in = dclkq3_stcntg; -- DCLKQ3_STATE;
-- was the working output pin that fed this obuf_DCLK.in
obuf_pld_DATA0.in = DATA0;
obuf_CONFIG_n_oe.in = B"0"; -- SPR 128193
-- Ye olde output enables:
obuf_A[].oe = drive_outputs;
obuf_flash_A22.oe = drive_outputs;
obuf_flash_A21.oe = drive_outputs;
obuf_flash_A20.oe = drive_outputs;
obuf_flash_CS_n.oe = drive_outputs;
obuf_flash_OE_n.oe = drive_outputs;
obuf_flash_RW_n.oe = drive_outputs;
obuf_DCLK.oe = drive_outputs;
obuf_pld_DATA0.oe = drive_outputs;
obuf_CONFIG_n_oe.oe = !CONFIG_n_reg.q; -- SPR 128193
-- Connect to the actual ouptut pins:
A[] = obuf_A[].out;
flash_A22 = obuf_flash_A22.out;
flash_A21 = obuf_flash_A21.out;
flash_A20 = obuf_flash_A20.out;
flash_CS_n = obuf_flash_CS_n.out;
flash_OE_n = obuf_flash_OE_n.out;
flash_RW_n = obuf_flash_RW_n.out;
DCLK = obuf_DCLK.out;
pld_DATA0 = obuf_pld_DATA0.out;
CONFIG_n = obuf_CONFIG_n_oe.out; -- SPR 128193 (was: CONFIG_n_reg.q)
-- I used these for debug pin assignments for the sake of simulation
-- DCLKQ3_STATE = dclkq3_stcntg; -- gain simulation respect
-- DCLKCOUT = dclk_en; -- gain simulation respect
-- DBCNTCOUT = The_Dclk_Divider.cout; -- gain simulation respect
-- DRIVE_OUT = drive_outputs; -- gain simulation respect
-- STATE_CNTG = State_Counting; -- gain simulation respect
-- Spare pin needed driven to accommodate the Cyclone
enet_VLBUS_n = B"1";
END;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -