📄 isp8_flow_cntl.vhd
字号:
------------------------------------------------------------------------------
--
-- Name: isp8_flow_cntl.vhd
--
-- Description: Flow control logic
--
-- $Revision: 1.3 $
--
------------------------------------------------------------------------------
-- Permission:
--
-- Lattice Semiconductor grants permission to use this code for use
-- in synthesis for any Lattice programmable logic product. Other
-- use of this code, including the selling or duplication of any
-- portion is strictly prohibited.
--
-- Disclaimer:
--
-- This VHDL or Verilog source code is intended as a design reference
-- which illustrates how these types of functions can be implemented.
-- It is the user's responsibility to verify their design for
-- consistency and functionality through the use of formal
-- verification methods. Lattice Semiconductor provides no warranty
-- regarding the use or functionality of this code.
------------------------------------------------------------------------------
--
-- Lattice Semiconductor Corporation
-- 5555 NE Moore Court
-- Hillsboro, OR 97124
-- U.S.A
--
-- TEL: 1-800-Lattice (USA and Canada)
-- 408-826-6000 (other locations)
--
-- web: http://www.latticesemi.com/
-- email: techsupport@latticesemi.com
--
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity isp8_flow_cntl is
generic(PROM_AW : natural;
FAMILY_NAME : string;
PGM_STACK_AW : natural;
PGM_STACK_AD : natural);
port(clk : in std_logic;
rst_n : in std_logic;
setc : in std_logic;
clrc : in std_logic;
setz : in std_logic;
clrz : in std_logic;
seti : in std_logic;
clri : in std_logic;
addr_jmp : in std_logic_vector((PROM_AW - 1) downto 0);
update_c : in std_logic;
update_z : in std_logic;
cout_alu : in std_logic;
dout_alu : in std_logic_vector(7 downto 0);
bz : in std_logic;
bnz : in std_logic;
bc : in std_logic;
bnc : in std_logic;
b : in std_logic;
callz : in std_logic;
callnz : in std_logic;
callc : in std_logic;
callnc : in std_logic;
call : in std_logic;
ret : in std_logic;
iret : in std_logic;
intr : in std_logic;
lsp : in std_logic;
lspi : in std_logic;
ssp : in std_logic;
sspi : in std_logic;
import : in std_logic;
importi : in std_logic;
export : in std_logic;
exporti : in std_logic;
ready : in std_logic;
addr_cyc : out std_logic;
ext_addr_cyc : out std_logic;
data_cyc : out std_logic;
prom_addr : out std_logic_vector((PROM_AW - 1) downto 0);
carry_flag : out std_logic;
intr_ack : out std_logic);
end isp8_flow_cntl;
architecture behave of isp8_flow_cntl is
component pmi_distributed_spram
generic (
pmi_addr_depth : integer;
pmi_addr_width : integer;
pmi_data_width : integer;
pmi_regmode : string;
pmi_init_file : string;
pmi_init_file_format : string;
pmi_family : string;
module_type : string := "pmi_distributed_spram"
);
port (
Address : in std_logic_vector(pmi_addr_width-1 downto 0);
Data : in std_logic_vector(pmi_data_width-1 downto 0);
Clock : in std_logic;
ClockEn : in std_logic;
WE : in std_logic;
Reset : in std_logic;
Q : out std_logic_vector(pmi_data_width-1 downto 0));
end component;
signal rst : std_logic;
signal lo_val : std_logic;
signal hi_val : std_logic;
signal carry_flag_int : std_logic;
signal zero_flag : std_logic;
signal ie_flag : std_logic;
signal pc, pc_int : std_logic_vector((PROM_AW - 1) downto 0);
signal addr_cyc_int : std_logic;
signal ext_addr_cyc_int : std_logic;
signal data_cyc_int : std_logic;
signal ret_reg : std_logic;
signal intr_req_actv_reg : std_logic;
signal dout_alu_reg : std_logic_vector(7 downto 0);
signal push_enb : std_logic;
signal intr_req_actv : std_logic;
signal intr_reg0 : std_logic;
signal addr_jmp_reg : std_logic_vector((PROM_AW - 1) downto 0);
signal prom_addr_int : std_logic_vector((PROM_AW - 1) downto 0);
signal br_enb, br_enb_reg : std_logic;
signal intr_ack_int : std_logic;
signal dout_stack : std_logic_vector((PROM_AW - 1) downto 0);
signal dout_stack_w_cz : std_logic_vector((PROM_AW + 1) downto 0);
signal din_stack_w_cz : std_logic_vector((PROM_AW + 1) downto 0);
signal pushed_zero, pushed_carry : std_logic;
signal sp_we : std_logic;
signal br_enb0 : std_logic;
signal stack_ptr : std_logic_vector(PGM_STACK_AW-1 downto 0);
signal condbr : std_logic;
signal ext_cycle_type : std_logic;
--attribute syn_black_box : boolean;
--attribute syn_black_box of pmi_distributed_spram: component is true;
begin
rst <= not rst_n;
lo_val <= '0';
hi_val <= '1';
condbr <= bz or bnz or bc or bnc or call or callz or callnz or callc or callnc;
ext_cycle_type <= (lspi or lsp or sspi or ssp or
export or exporti or import or
importi);
process(clk, rst_n)
begin
if (rst_n = '0') then
addr_cyc_int <= '0';
ext_addr_cyc_int <= '0';
data_cyc_int <= '0';
elsif rising_edge(clk) then
addr_cyc_int <= (NOT(addr_cyc_int) and (not(ext_addr_cyc_int)));
ext_addr_cyc_int <= (addr_cyc_int and ext_cycle_type) or
(ext_addr_cyc_int and not ready);
data_cyc_int <= (addr_cyc_int and not ext_cycle_type) or
(ext_addr_cyc_int and ready);
end if;
end process;
addr_cyc <= addr_cyc_int;
ext_addr_cyc <= ext_addr_cyc_int;
data_cyc <= data_cyc_int;
process(clk, rst_n)
begin
if (rst_n = '0') then
ret_reg <= '0';
intr_req_actv_reg <= '0';
dout_alu_reg <= "00000000";
elsif rising_edge(clk) then
ret_reg <= (ret OR iret);
intr_req_actv_reg <= intr_req_actv;
dout_alu_reg <= dout_alu;
end if;
end process;
process(clk, rst_n)
begin
if (rst_n = '0') then
intr_reg0 <= '0';
elsif rising_edge(clk) then
if (addr_cyc_int = '1') then
intr_reg0 <= ie_flag and intr and not condbr;
else
intr_reg0 <= intr_reg0;
end if;
end if;
end process;
process(clk, rst_n)
begin
if (rst_n = '0') then
addr_jmp_reg <= (others => '0');
br_enb_reg <= '0';
elsif rising_edge(clk) then
if (addr_cyc_int = '1') then
addr_jmp_reg <= addr_jmp;
br_enb_reg <= br_enb;
end if;
end if;
end process;
intr_req_actv <= (intr_reg0 AND NOT(intr_ack_int));
-- Push enable to store in stack
push_enb <= ((callz AND zero_flag) OR (callc AND carry_flag_int) OR
(callnz AND NOT(zero_flag)) OR (callnc AND NOT(carry_flag_int)) OR call);
-- Branch enable to branch out the programm counter
br_enb0 <= ((bz AND zero_flag) OR (bc AND carry_flag_int) OR
(bnz AND NOT zero_flag) OR (bnc AND NOT carry_flag_int)) ;
br_enb <= ((bz AND zero_flag) OR (bc AND carry_flag_int) OR
(bnz AND NOT(zero_flag)) OR (bnc AND NOT(carry_flag_int)) OR b OR push_enb);
-- program coumter
-- Incremented every address cycle (2 clocks) and
-- loaded with stack with return instruction.
-- loaded interrupt vector with interrupt.
pc_int <= (pc + addr_jmp_reg) when ((br_enb_reg = '1') AND (data_cyc_int = '1')) else pc + '1';
process(intr_req_actv, ret_reg, dout_stack, pc_int, push_enb, br_enb0, data_cyc_int)
begin
if (data_cyc_int = '1') and (intr_req_actv = '1') and (push_enb = '0') and (br_enb0 = '0') then
-- taking an interrupt
prom_addr_int <= (others => '0');
else
if (ret_reg = '1') then
-- returning from interrupt, pull return address from the stack
prom_addr_int <= dout_stack;
else
-- normal straight line/jump instruction
prom_addr_int <= pc_int;
end if;
end if;
end process;
prom_addr <= prom_addr_int;
process(clk, rst_n)
begin
if (rst_n = '0') then
pc <= (others => '0');
elsif rising_edge(clk) then
if (data_cyc_int = '1') then
pc <= prom_addr_int;
end if;
end if;
end process;
-- Carry flag
process(clk,rst_n)
begin
if (rst_n = '0') then
carry_flag_int <= '0';
elsif rising_edge(clk) then
if ((clrc = '1') OR (setc = '1') OR (update_c = '1') OR (iret = '1')) then
carry_flag_int <= (NOT(clrc) AND ((update_c AND cout_alu) OR setc OR (iret AND pushed_carry)));
else
carry_flag_int <= carry_flag_int;
end if;
end if;
end process;
carry_flag <= carry_flag_int;
-- Zero flag
process(clk,rst_n)
begin
if (rst_n = '0') then
zero_flag <= '0';
elsif rising_edge(clk) then
if ((clrz = '1') OR (setz = '1') OR (update_z = '1') OR (iret = '1')) then
zero_flag <= ((update_z AND data_cyc_int AND
NOT(dout_alu_reg(0) OR
dout_alu_reg(1) OR
dout_alu_reg(2) OR
dout_alu_reg(3) OR
dout_alu_reg(4) OR
dout_alu_reg(5) OR
dout_alu_reg(6) OR
dout_alu_reg(7)))
OR (iret AND pushed_zero)
OR setz);
else
zero_flag <= zero_flag;
end if;
end if;
end process;
-- Interrupt Enable flag
process(clk,rst_n)
begin
if (rst_n = '0') then
ie_flag <= '0';
elsif rising_edge(clk) then
if ((clri = '1') OR (seti = '1')) then
ie_flag <= NOT(clri);
else
ie_flag <= ie_flag;
end if;
end if;
end process;
-- Generate interrupt acknowledge
-- Asserted as long as in interrupt service routine
process(clk,rst_n)
begin
if (rst_n = '0') then
intr_ack_int <= '0';
elsif rising_edge(clk) then
if ((data_cyc_int = '1') and (intr_req_actv = '1') and (push_enb = '0') and (br_enb0 = '0')) then
intr_ack_int <= '1';
elsif (iret = '1' and data_cyc_int = '1') then
intr_ack_int <= '0';
else
intr_ack_int <= intr_ack_int;
end if;
end if;
end process;
intr_ack <= intr_ack_int;
sp_we <= (addr_cyc_int AND push_enb) OR
(data_cyc_int AND intr_req_actv and
((not push_enb) and (not br_enb0)));
u1_isp8_stkmem : pmi_distributed_spram
generic map (
pmi_addr_depth => PGM_STACK_AD,
pmi_addr_width => PGM_STACK_AW,
pmi_data_width => (PROM_AW+2),
pmi_regmode => "noreg",
pmi_init_file => "none",
pmi_init_file_format => "binary",
pmi_family => FAMILY_NAME)
port map (
Address => stack_ptr,
Data => din_stack_w_cz,
Clock => clk,
ClockEn => hi_val,
WE => sp_we,
Reset => lo_val,
Q => dout_stack_w_cz);
din_stack_w_cz <= carry_flag_int & zero_flag & pc_int;
dout_stack <= dout_stack_w_cz(PROM_AW - 1 downto 0);
pushed_carry <= dout_stack_w_cz(PROM_AW + 1);
pushed_zero <= dout_stack_w_cz(PROM_AW);
-- Stack pointer
process(clk, rst_n)
begin
if (rst_n = '0') then
stack_ptr <= (others => '0');
elsif rising_edge(clk) then
if ((data_cyc_int = '1') AND ((push_enb = '1') OR (intr_req_actv = '1'))) then
stack_ptr <= stack_ptr + '1';
elsif ((addr_cyc_int = '1') AND ((ret = '1') OR (iret = '1'))) then
stack_ptr <= stack_ptr - '1';
end if;
end if;
end process;
end behave;
--------------------------------- E O F --------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -