📄 control_mem.vhd
字号:
begin
-- some simple assignments
pc_o <= std_logic_vector(pc_comb);
pc_plus1 <= pc + conv_unsigned(1,1);
pc_plus2 <= pc + conv_unsigned(2,2);
ram_adr_o <= std_logic_vector(s_adr(6 downto 0));
reg_data_o <= std_logic_vector(s_reg_data);
ram_data_o <= std_logic_vector(s_data);
acc_o <= std_logic_vector(acc);
cy_o(1) <= cy;
ov_o <= ov;
cy_o(0) <= ac;
ie_o <= ie;
ip_o <= ip;
psw_o <= psw;
state_o <= state;
command_o <= s_command;
ri_o <= s_ri;
ti_o <= s_ti;
help_o <= std_logic_vector(s_help);
bit_data_o <= s_bit_data;
intpre_o <= s_intpre;
intpre2_o <= s_intpre2;
inthigh_o <= s_inthigh;
intlow_o <= s_intlow;
tf1_o <= s_tf1;
tf0_o <= s_tf0;
ie1_o <= s_ie1;
ie0_o <= s_ie0;
s_pc_inc_en <= pc_inc_en_i;
s_nextstate <= nextstate_i;
s_adr_mux <= adr_mux_i;
s_adrx_mux <= adrx_mux_i;
s_data_mux <= data_mux_i;
s_bdata_mux <= bdata_mux_i;
s_regs_wr_en <= regs_wr_en_i;
s_help_en <= help_en_i;
s_help16_en <= help16_en_i;
s_helpb_en <= helpb_en_i;
s_inthigh_en <= inthigh_en_i;
s_intlow_en <= intlow_en_i;
s_intpre2_en <= intpre2_en_i;
s_inthigh_d <= inthigh_d_i;
s_intlow_d <= intlow_d_i;
s_intpre2_d <= intpre2_d_i;
s_tsel <= conv_integer(tsel) when tsel < C_IMPL_N_TMR
else conv_integer(0); -- selected timer unit is (not) implemented
s_ssel <= conv_integer(ssel) when ssel < C_IMPL_N_SIU
else conv_integer(0); -- selected siu unit is (not) implemented
for_tmr:
for i in 0 to C_IMPL_N_TMR-1 generate
all_tcon_tr0_o(i) <= tcon(i)(4);
all_tcon_tr1_o(i) <= tcon(i)(6);
all_tmod_o((i*8)+7 downto i*8) <= std_logic_vector(tmod(i));
s_tl0(i) <= unsigned(all_tl0_i((i*8)+7 downto i*8));
s_tl1(i) <= unsigned(all_tl1_i((i*8)+7 downto i*8));
s_th0(i) <= unsigned(all_th0_i((i*8)+7 downto i*8));
s_th1(i) <= unsigned(all_th1_i((i*8)+7 downto i*8));
all_reload_o((i*8)+7 downto i*8) <= std_logic_vector(s_reload(i));
all_wt_o((i*2)+1 downto i*2) <= std_logic_vector(s_wt(i));
end generate for_tmr;
s_tf1 <= tcon(s_tsel)(7);
s_tf0 <= tcon(s_tsel)(5);
s_ie1 <= tcon(s_tsel)(3);
s_ie0 <= tcon(s_tsel)(1);
for_siu:
for i in 0 to C_IMPL_N_SIU-1 generate
all_scon_o((6*i)+5) <= scon(i)(0); -- RI
all_scon_o((6*i)+4) <= scon(i)(7); -- SM0
all_scon_o((6*i)+3) <= scon(i)(6); -- SM1
all_scon_o((6*i)+2) <= scon(i)(5); -- SM2
all_scon_o((6*i)+1) <= scon(i)(4); -- REN
all_scon_o(6*i) <= scon(i)(3); -- TB8
all_smod_o(i) <= s_smodreg(i); -- SMOD
all_sbuf_o((8*i)+7 downto 8*i) <= std_logic_vector(sbuf(i));
s_sbufi(i) <= unsigned(all_sbuf_i((i*8)+7 downto i*8));
end generate for_siu;
s_sm0 <= scon(s_ssel)(7);
s_sm1 <= scon(s_ssel)(6);
s_sm2 <= scon(s_ssel)(5);
s_ren <= scon(s_ssel)(4);
s_tb8 <= scon(s_ssel)(3);
s_rb8 <= all_scon_i((s_ssel*3)+2);
s_ti <= scon(s_ssel)(1);
s_ri <= scon(s_ssel)(0);
s_smod<= s_smodreg(s_ssel);
p0_o <= std_logic_vector(p0);
p1_o <= std_logic_vector(p1);
p2_o <= std_logic_vector(p2);
p3_o <= std_logic_vector(p3);
s_p <= acc(7) xor acc(6) xor acc(5) xor acc(4) xor
acc(3) xor acc(2) xor acc(1) xor acc(0);
-- P should be set, if the count
-- of 1 in the acc is even
s_command <= rom_data_i when state=FETCH
else conv_std_logic_vector(s_ir,8);
s_rr_adr <= unsigned((psw and "00011000") or (rom_data_i
and "00000111")); -- calculate registerdirect-adress
s_ri_adr <= ((psw and "00011000") or (s_command(7 downto 0) and "00000001"));
datax_o <= std_logic_vector(acc);
wrx_o <= wrx_mux_i;
-- This logic ensures that a pending interrupt is not serviced if
-- a) RETI instruction is in progress,
-- b) any write to IE or IP register is in progress.
s_intblock <= '1' when (std_logic_vector(s_ir) = RETI) or -- RETI in progress
(s_regs_wr_en = "100" and -- \
(conv_integer(s_adr) = 16#B8# or -- | write to
conv_integer(s_adr) = 16#A8#) and -- | IE or IP
s_intpre2 = '0') or -- /
(s_regs_wr_en = "110" and -- \
(s_adr(7 downto 3) = conv_unsigned(21,5) or -- | bit access
s_adr(7 downto 3) = conv_unsigned(23,5)) and -- | to IE v IP
s_intpre2 = '0') else '0'; -- /
------------------------------------------------------------------------------
-- purpose: process to read SFR, bitadressable or normal RAM
-- inputs: s_adr,s_preadr,sp,dpl,dph,pcon,tcon,tmod,all_tl0_i,
-- all_tl1_i,all_th0_i,all_th1_i,s_p0,s_p1,all_scon_i,all_sbuf_i,
-- s_p2,ie,s_p3,ip,psw,acc,b,gprbit,ram_data_i
-- outputs: s_reg_data, s_bit_data
------------------------------------------------------------------------------
p_readram : process (s_preadr,s_p0,sp,dpl,dph,pcon,tcon,tmod,s_p1,scon,s_p2,
ie,s_p3,ip,psw,acc,b,gprbit,ram_data_i,s_r0_b0,s_r1_b0,
s_r0_b1,s_r1_b1,s_r0_b2,s_r1_b2,s_r0_b3,s_r1_b3,
s_smod,s_sm0,s_sm1,s_sm2,s_ren,s_tb8,s_rb8,s_ti,s_ri,
s_sbufi,s_th1,s_th0,s_ssel,s_tsel,s_tl1,s_tl0,
ssel,tsel)
begin
if s_preadr(7)='1' then
case conv_integer(s_preadr) is -- read one byte of a SFR
when 16#80# => s_reg_data <= unsigned(s_p0);
when 16#81# => s_reg_data <= sp;
when 16#82# => s_reg_data <= dpl;
when 16#83# => s_reg_data <= dph;
when 16#87# =>
s_reg_data(7) <= s_smod;
s_reg_data(6 downto 4) <= "000";
s_reg_data(3 downto 0) <= pcon;
when 16#88# => s_reg_data <= unsigned(tcon(s_tsel));
when 16#89# => s_reg_data <= unsigned(tmod(s_tsel));
when 16#8A# => s_reg_data <= s_tl0(s_tsel);
when 16#8B# => s_reg_data <= s_tl1(s_tsel);
when 16#8C# => s_reg_data <= s_th0(s_tsel);
when 16#8D# => s_reg_data <= s_th1(s_tsel);
when 16#8E# => s_reg_data <= tsel;
when 16#90# => s_reg_data <= unsigned(s_p1);
when 16#98# =>
s_reg_data(0) <= s_ri; -- from SCON register
s_reg_data(1) <= s_ti; -- from SCON register
s_reg_data(2) <= s_rb8; -- read extern input!!!
s_reg_data(3) <= s_tb8;
s_reg_data(4) <= s_ren;
s_reg_data(5) <= s_sm2;
s_reg_data(6) <= s_sm1;
s_reg_data(7) <= s_sm0;
when 16#99# => s_reg_data <= s_sbufi(s_ssel);
when 16#9A# => s_reg_data <= ssel;
when 16#A0# => s_reg_data <= unsigned(s_p2);
when 16#A8# => s_reg_data <= unsigned(ie);
when 16#B0# => s_reg_data <= unsigned(s_p3);
when 16#B8# => s_reg_data <= unsigned(ip);
when 16#D0# => s_reg_data <= unsigned(psw);
when 16#E0# => s_reg_data <= acc;
when 16#F0# => s_reg_data <= b;
when others => s_reg_data <= conv_unsigned(0,8);
end case;
-- read one byte to bitadressable GPR
elsif conv_std_logic_vector(s_preadr(7 downto 4),4)="0010" then
s_reg_data <= gprbit(conv_integer(s_preadr(3 downto 0)));
elsif conv_std_logic_vector(s_preadr,8)="00000000" then
s_reg_data <= s_r0_b0; -- read R0 / Bank 0
elsif conv_std_logic_vector(s_preadr,8)="00000001" then
s_reg_data <= s_r1_b0; -- read R1 / Bank 0
elsif conv_std_logic_vector(s_preadr,8)="00001000" then
s_reg_data <= s_r0_b1; -- read R0 / Bank 1
elsif conv_std_logic_vector(s_preadr,8)="00001001" then
s_reg_data <= s_r1_b1; -- read R1 / Bank 1
elsif conv_std_logic_vector(s_preadr,8)="00010000" then
s_reg_data <= s_r0_b2; -- read R0 / Bank 2
elsif conv_std_logic_vector(s_preadr,8)="00010001" then
s_reg_data <= s_r1_b2; -- read R1 / Bank 2
elsif conv_std_logic_vector(s_preadr,8)="00011000" then
s_reg_data <= s_r0_b3; -- read R0 / Bank 3
elsif conv_std_logic_vector(s_preadr,8)="00011001" then
s_reg_data <= s_r1_b3; -- read R1 / Bank 3
else -- read on general purpose RAM
s_reg_data <= unsigned(ram_data_i);
end if;
if s_preadr(7)='1' then
case s_preadr(6 downto 3) is -- read only one bit from a SFR
when "0000" => s_bit_data <= s_p0(conv_integer(s_preadr(2 downto 0)));
when "0001" =>
s_bit_data <= tcon(s_tsel)(conv_integer(s_preadr(2 downto 0)));
when "0010" => s_bit_data <= s_p1(conv_integer(s_preadr(2 downto 0)));
when "0011" =>
if conv_integer(s_preadr(2 downto 0))=2 then
s_bit_data <= s_rb8;
else
s_bit_data <= scon(s_ssel)(conv_integer(s_preadr(2 downto 0)));
end if;
when "0100" => s_bit_data <= s_p2(conv_integer(s_preadr(2 downto 0)));
when "0101" => s_bit_data <= ie(conv_integer(s_preadr(2 downto 0)));
when "0110" => s_bit_data <= s_p3(conv_integer(s_preadr(2 downto 0)));
when "0111" => s_bit_data <= ip(conv_integer(s_preadr(2 downto 0)));
when "1010" => s_bit_data <= psw(conv_integer(s_preadr(2 downto 0)));
when "1100" => s_bit_data <= acc(conv_integer(s_preadr(2 downto 0)));
when "1110" => s_bit_data <= b(conv_integer(s_preadr(2 downto 0)));
when others => s_bit_data <= '0';
end case;
else -- read one bit from bitadressable GP
s_bit_data <= gprbit(conv_integer(s_preadr(6 downto 3)))
(conv_integer(s_preadr(2 downto 0)));
end if;
end process p_readram;
------------------------------------------------------------------------------
-- detect the rising/falling edge of interupt-sources
------------------------------------------------------------------------------
for_intext_edge:
for i in 0 to C_IMPL_N_EXT-1 generate
-- falling edge of int0_i
s_int0_edge(i) <= not s_int0_h2(i) and s_int0_h3(i);
-- falling edge of int1_i
s_int1_edge(i) <= not s_int1_h2(i) and s_int1_h3(i);
end generate for_intext_edge;
for_tf_edge:
for i in 0 to C_IMPL_N_TMR-1 generate
-- on rising edge of tf0_i
s_tf0_edge(i) <= s_tf0_h1(i) and not s_tf0_h2(i);
-- on rising edge of tf1_i
s_tf1_edge(i) <= s_tf1_h1(i) and not s_tf1_h2(i);
end generate for_tf_edge;
for_siu_edge:
for i in 0 to C_IMPL_N_SIU-1 generate
-- on rising edge of RI
s_ri_edge(i) <= s_ri_h1(i) and not s_ri_h2(i);
-- on rising edge of TI
s_ti_edge(i) <= s_ti_h1(i) and not s_ti_h2(i);
end generate for_siu_edge;
------------------------------------------------------------------------------
-- purpose: write some help-regs for detecting the falling/rising edge
-- of interupt-sources
-- inputs: clk,reset,int0_i,int1_i,all_tf0_i,all_tf1_i,all_scon_i,
-- s_tf0_h1,s_tf1_h1,s_ri_h1,s_ti_h1
-- outputs: s_int0_h1,s_int0_h2,s_int0_h3,s_int1_h1,s_int1_h2,s_int1_h3,
-- s_tf0_h1,s_tf0_h2
-- s_tf1_h1,s_tf1_h2,s_ri_h1,s_ri_h2,s_ti_h1,s_ti_h2
------------------------------------------------------------------------------
iep: process (clk,reset)
begin -- process iep
-- activities triggered by asynchronous reset
if reset = '1' then
s_int0_h1 <= (others => '1');
s_int0_h2 <= (others => '1');
s_int0_h3 <= (others => '1');
s_int1_h1 <= (others => '1');
s_int1_h2 <= (others => '1');
s_int1_h3 <= (others => '1');
s_tf0_h1 <= (others => '0');
s_tf0_h2 <= (others => '0');
s_tf1_h1 <= (others => '0');
s_tf1_h2 <= (others => '0');
s_ri_h1 <= (others => '0');
s_ri_h2 <= (others => '0');
s_ti_h1 <= (others => '0');
s_ti_h2 <= (others => '0');
intblock_o <= '0';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -