📄 uc_interface.vhd
字号:
cntrl_en <= '0'; -- control register enable
stat_en <= '0'; -- status register enable
-- Synchronize with rising edge of clock
elsif clk'event and (clk = '1') then
if ale_n = '0' and psen_n = '1'
and address(15 downto (15-(DEVICE_ADDR_BITS-1))) = BASE_ADDR then
-- base address matches and address is stable
addr_match <= '1';
-- Check appropriate register address
case address(REG_ADDR_BITS-1 downto 0) is
when STATUS_ADDR => -- status register has been addressed
stat_en <= '1';
cntrl_en <= '0';
datain_en <= '0';
dataout_en <= '0';
when CTRL_ADDR => -- control register has been addressed
stat_en <= '0';
cntrl_en <= '1';
datain_en <= '0';
dataout_en <= '0';
when DATAIN_ADDR => -- input data register has been addressed
stat_en <= '0';
cntrl_en <= '0';
datain_en <= '1';
dataout_en <= '0';
when DATAOUT_ADDR => -- toutput data register has been addressed
stat_en <= '0';
cntrl_en <= '0';
datain_en <= '0';
dataout_en <= '1';
when others => -- error condition, no registers are enabled
stat_en <= '0';
cntrl_en <= '0';
datain_en <= '0';
dataout_en <= '0';
end case;
else
-- this device is not addressed
addr_match <= '0';
stat_en <= '0';
cntrl_en <= '0';
datain_en <= '0';
dataout_en <= '0';
end if;
end if;
end process;
--************************** Read/Write uC registers **********************************
-- This process reads data from or writes data to the enabled register
register_rw: process(clk, reset)
begin
-- Initialize all internal registers upon reset
if reset = RESET_ACTIVE then
-- Status Register
error_reset <= RESET_ACTIVE; -- write to this bit clears it
int_reset <= RESET_ACTIVE; -- write to this bit clears it
-- Control Register
app_en <= '0'; -- enables the SPI interface
int_en <= '0'; -- enables interrupts
start <= '0'; -- instructs application to start operation
ctrl_bits <= (others => '0'); -- general purpose control bits
-- Input data register
data_in <= (others => '0'); -- initialize input data to 0
need_data_reset <= (RESET_ACTIVE); -- when input data register is written,
-- the need_data flag is reset
-- Output data register
data_rdy_reset <= (RESET_ACTIVE); -- when output data register is read, the
-- data_rdy flag is reset
-- Initialize uc output data bus
uc_data_out <= (others => '0');
-- Check for rising edge of clock
elsif clk'event and (clk = '1') then
-- Check for data transfer state
if (prs_state = DATA_TRS) then
-- Control Register
if cntrl_en = '1' then
if wr_n = '0' then
-- uC write
app_en <= uc_data_in(7);
int_en <= uc_data_in(6);
start <= uc_data_in(5);
ctrl_bits <= uc_data_in(4 downto 0);
end if;
if rd_n = '0' then
-- uC read
uc_data_out <= app_en & int_en & start & ctrl_bits;
end if;
end if;
-- Status Register
-- this register is created in the proces STATUSREG_PROCESS
-- note that if the status bits from the application logic
-- are registered, they can be concatenated here when assigned
-- to uc_data_out
if stat_en = '1' then
if wr_n = '0' then
-- uC write to the error bit resets this bit
if uc_data_in(6) = '0' then
error_reset <= RESET_ACTIVE;
else
error_reset <= not(RESET_ACTIVE);
end if;
-- uC write to the int_n bit resets this bit
if uc_data_in(5) = '0' then
int_reset <= RESET_ACTIVE;
else
int_reset <= not(RESET_ACTIVE);
end if;
end if;
if rd_n = '0' then
-- uC read
uc_data_out <= status_reg;
end if;
end if;
-- Input Data Register
if datain_en = '1' then
if wr_n = '0' then
-- uC write
data_in <= uc_data_in;
-- reset the empty flag
need_data_reset <= RESET_ACTIVE;
end if;
if rd_n = '0' then
-- uC Read
uc_data_out <= data_in;
end if;
end if;
-- Output Data Register
-- this register is created in the process OUTPUTREG_PROCESS
if dataout_en = '1' then
if rd_n = '0' then
-- uC Read
uc_data_out <= data_out;
-- reset the data_rdy
data_rdy_reset <= RESET_ACTIVE;
end if;
end if;
else
need_data_reset <= not(RESET_ACTIVE);
data_rdy_reset <= not(RESET_ACTIVE);
error_reset <= not(RESET_ACTIVE);
int_reset <= not(RESET_ACTIVE);
end if;
end if;
end process;
--************************** Status Register **********************************
-- This process registers the status signals from the application logic to
-- create the status register. It is synchronously reset when APP_EN is negated
-- NOTE: if these bits are registered in the application
-- logic, there is no need for this process; the bits can be concatenated in the
-- register read/write process to assign to UC_DATA_OUT when the status register
-- is being read
-- NOTE: The interrupt bit, INT_N, is generated by the uc_interface logic in the
-- process INTERRUPT_PROCESS, not by the application logic
statusreg_process: process(clk, reset)
begin
if reset = RESET_ACTIVE then
status_reg <= (others => '0');
elsif clk'event and clk = '1' then
-- reset this register synchronously when
-- app_en is negated
if app_en = '0' then
status_reg <= (others => '0'); -- int_n is active low, reset to '1'
else
status_reg <= done & error & not(int_n) & need_data & data_rdy & "000";
end if;
end if;
end process;
--************************** Output Data Register **********************************
-- This process implements the bits in the Output Data register
-- this register is synchronously reset when APP_EN is negated
outputreg_process: process(clk, reset)
begin
if reset = RESET_ACTIVE then
data_out <= (others => '0');
elsif clk'event and clk = '1' then
-- reset this register synchronously when
-- app_en is negated
if app_en = '0' then
data_out <= (others => '0');
elsif dataout_load = '1' then
-- load the receive register
data_out <= app_data;
else
data_out <= data_out;
end if;
end if;
end process;
--************************** Interrupt Logic **********************************
-- This process implements asserts an interrupt whenever NEED_DATA, ERROR, or
-- DATA_RDY is asserted. Interrupt service routine should read the status register
-- to determine the cause of the interrupt.
-- NOTE: This logic should be modified to match the interrupt requirements of the application
interrupt_process: process(clk, reset)
begin
if reset = RESET_ACTIVE then
int_n <= '1';
elsif clk'event and clk = '1' then
if int_reset = RESET_ACTIVE then
int_n <= '1';
elsif int_en = '1' then
-- interrupts are enabled
-- interrupt processor if there ERROR, NEED_DATA, or DATA_RDY are
-- asserted
if error = '1' or (need_data = '1' and start = '1') or
(data_rdy = '1' and start = '0') then
int_n <= '0';
end if;
end if;
end if;
end process;
end BEHAVIOUR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -