📄 dsp_interface.vhd
字号:
dsp_data_en <= '0';
dsp_status_en <= '1';
dsp_address_match <= '1';
when others =>
dsp_addr_en <= '0';
dsp_data_en <= '0';
dsp_status_en <= '0';
dsp_address_match <= '0';
end case;
elsif (dsp_ioms_n = '0' and dsp_address_match = '1') then
dsp_addr_en <= dsp_addr_en;
dsp_data_en <= dsp_data_en;
dsp_status_en <= dsp_status_en;
dsp_address_match <= dsp_address_match;
else
dsp_addr_en <= '0';
dsp_data_en <= '0';
dsp_status_en <= '0';
dsp_address_match <= '0';
end if;
end if;
end process;
--******************* CF+ Interface Address Decode ********************
cf_addr_decode: process (io_reset, dsp_clk, prs_state, io_addr, io_write_n_sync, io_address_match)
begin
if io_reset = '0' then
io_addr_en <= '0';
io_data_en <= '0';
io_status_en <= '0';
io_address_match <= '0';
elsif (dsp_clk'event and dsp_clk = '0') then
if prs_state = CF_ADDR_STATE then
case io_addr(10 downto 0) is
when CF_ADDR_REG =>
io_addr_en <= '1';
io_data_en <= '0';
io_status_en <= '0';
io_address_match <= '1';
when CF_DATA_REG =>
io_addr_en <= '0';
io_data_en <= '1';
io_status_en <= '0';
io_address_match <= '1';
when CF_STATUS_REG =>
io_addr_en <= '0';
io_data_en <= '0';
io_status_en <= '1';
io_address_match <= '1';
when others =>
io_addr_en <= '0';
io_data_en <= '0';
io_status_en <= '0';
io_address_match <= '0';
end case;
elsif (io_address_match = '1' and (io_write_n_sync = '0' or io_read_n_sync = '0')) then
io_addr_en <= io_addr_en;
io_data_en <= io_data_en;
io_status_en <= io_status_en;
io_address_match <= io_address_match;
else
io_addr_en <= '0';
io_data_en <= '0';
io_status_en <= '0';
io_address_match <= '0';
end if;
end if;
end process;
--*********************** Read from I/O Registers *************************
read_io_registers: process(io_addr_reg, io_data_reg, io_status_reg, prs_state, io_read_n_sync, io_write_n_sync, dsp_rd_n, dsp_wr_n, dsp_addr_en, dsp_data_en, dsp_status_en, io_addr_en, io_data_en, io_status_en)
begin
-- CF+ interface read
if prs_state = CF_DATA_READ_STATE then
-- Address Register
if io_addr_en = '1' then
io_data_r <= io_addr_reg;
-- Data Register
elsif io_data_en = '1' then
io_data_r <= io_data_reg;
-- Status Register
elsif io_status_en = '1' then
io_data_r <= io_status_reg;
end if;
-- DSP interface read
elsif prs_state = DSP_DATA_READ_STATE then
-- Address Register
if dsp_addr_en = '1' then
data_out <= io_addr_reg;
-- Data Register
elsif dsp_data_en = '1' then
data_out <= io_data_reg;
-- Status Register
elsif dsp_status_en = '1' then
data_out <= io_status_reg;
end if;
else
io_data_r <= (others => '0');
data_out <= (others => '0');
end if;
end process;
--*********************** Write to I/O Registers *************************
write_io_registers: process(dsp_clk, io_reset, prs_state, dsp_addr_en, dsp_data_en, io_addr_en, io_data_en)
begin
if io_reset = '0' then
io_addr_reg <= (others => '0');
io_data_reg <= (others => '0');
io_data_done <= '0';
dsp_data_done <= '0';
elsif (dsp_clk'event and dsp_clk = '1') then
if prs_state = CF_DATA_WRITE_STATE then
-- Address Register
if (io_addr_en = '1' and io_status_reg(7) = '0' and iowr_n = '1') then
io_addr_reg <= io_data_w;
io_data_done <= '1';
-- Data Register
elsif (io_data_en = '1' and io_status_reg(7) = '0' and iowr_n = '1') then
io_data_reg <= io_data_w;
io_data_done <= '1';
end if;
elsif (prs_state = DSP_DATA_WRITE_STATE and dsp_data_done = '0' and dsp_ioms_n = '0') then
-- Address Register
if (dsp_addr_en = '1' and io_status_reg(6) = '0') then
io_addr_reg <= data_in;
dsp_data_done <= '1';
-- Data Register
elsif (dsp_data_en = '1' and io_status_reg(6) = '0') then
io_data_reg <= data_in;
dsp_data_done <= '1';
end if;
else
io_addr_reg <= io_addr_reg;
io_data_reg <= io_data_reg;
io_data_done <= '0';
dsp_data_done <= '0';
end if;
end if;
end process;
--**************************** Status Register ****************************
new_data: process (io_reset, dsp_clk, dsp_data_done, io_data_done, io_status_reg, prs_state)
begin
if io_reset = '0' then
io_status_reg <= (others => '0');
elsif (dsp_clk'event and dsp_clk = '1') then
-- New data from DSP
if dsp_data_done = '1' then
-- IRQ for CF+ interface (IRQ_CF)
if io_status_reg(7) = '0' then
io_status_reg(7) <= '1'; -- IRQ due to new data in address/data register from DSP
end if;
-- New Data in Data Register (DataReg)
if io_status_reg(1) = '0' then
io_status_reg(1) <= dsp_data_en; -- Data register needs to be read
end if;
-- New Data in Address Register (AddrReg)
if io_status_reg(0) = '0' then
io_status_reg(0) <= dsp_addr_en; -- Address register needs to be read
end if;
-- Data has been read from Address/Data registers by CF+ interface
elsif prs_state = CF_DATA_READ_STATE then
io_status_reg(7) <= '0';
io_status_reg(6) <= io_status_reg(6);
io_status_reg(1) <= '0';
io_status_reg(0) <= '0';
-- New data from CF+ interface
elsif io_data_done = '1' then
-- IRQ for DSP interface (IRQ_DSP)
if io_status_reg(6) = '0' then
io_status_reg(6) <= '1'; -- IRQ due to new data in address/data register from CF+ interface
end if;
-- New Data in Data Register (DataReg)
if io_status_reg(1) = '0' then
io_status_reg(1) <= io_data_en; -- Data register needs to be read
end if;
-- New Data in Address Register (AddrReg)
if io_status_reg(0) = '0' then
io_status_reg(0) <= io_addr_en; -- Address register needs to be read
end if;
-- Data has been read from Address/Data registers by DSP
elsif prs_state = DSP_DATA_READ_STATE then
io_status_reg(7) <= io_status_reg(7);
io_status_reg(6) <= '0';
io_status_reg(1) <= '0';
io_status_reg(0) <= '0';
else
io_status_reg(7) <= io_status_reg(7);
io_status_reg(6) <= io_status_reg(6);
io_status_reg(1) <= io_status_reg(1);
io_status_reg(0) <= io_status_reg(0);
end if;
end if;
end process;
--******************************* CF+ interface IRQ logic *******************************
io_irq_pending <= io_status_reg(7); -- for INT bit of CSR
cf_irq: process (io_reset, dsp_clk, io_status_reg(7), level_pulse_n, irq_count)
begin
if io_reset = '0' then
io_irq_n <= '1';
irq_count_clr <= '0';
elsif (dsp_clk'event and dsp_clk = '1') then
if io_status_reg(7) = '1' then
-- Pulse Mode IRQ for CF+ interface
if level_pulse_n = '0' then
-- end of pulse
if irq_count >= IRQ_TERM_COUNT then
irq_count_clr <= '1';
irq_count_en <= '0';
io_irq_n <= '1';
else
irq_count_clr <= '1';
irq_count_en <= '1';
io_irq_n <= '0';
end if;
-- Level Mode IRQ for CF+ interface
else
irq_count_clr <= '0';
irq_count_en <= '0';
io_irq_n <= '0';
end if;
else
irq_count_clr <= '0';
irq_count_en <= '0';
io_irq_n <= '1';
end if;
end if;
end process;
up_counter: upcnt6
port map(
cnt_en => irq_count_en,
clr => irq_count_clr,
clk => dsp_clk,
qout => irq_count
);
end behave;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -