📄 control_mem.vhd
字号:
-- inputs: s_pc_inc_en,pc_plus1,rom_data_i,s_intpre2,s_help,s_command,
-- s_help16,s_ir,dph,dpl,acc,s_reg_data,pc
-- outputs: pc_comb
------------------------------------------------------------------------------
p_pc : process (s_pc_inc_en,pc_plus1,rom_data_i,s_help,
s_help16,s_ir,dph,dpl,acc,s_reg_data,pc)
variable v_dptr: unsigned(15 downto 0);
begin
v_dptr(15 downto 8) := dph;
v_dptr(7 downto 0) := dpl;
case s_pc_inc_en is
when "0001" => -- increment PC
pc_comb <= pc_plus1;
when "0010" => -- for relativ jumps and calls
pc_comb <= conv_unsigned(pc_plus1 + signed(rom_data_i),16);
when "0011" => -- load interrupt vectoradress
pc_comb(15 downto 8) <= conv_unsigned(0,8);
pc_comb(7 downto 0) <= s_help;
when "0100" => -- ACALL and AJMP
pc_comb(15 downto 11) <= s_help16(15 downto 11);
pc_comb(10 downto 8) <= s_ir(7 downto 5);
pc_comb(7 downto 0) <= unsigned(rom_data_i);
when "0101" => -- JMP_A_DPTR, MOVC_A_ATDPTR
pc_comb <= v_dptr + conv_unsigned(acc,8);
when "0110" => -- MOVC
pc_comb <= s_help16;
when "0111" => -- LJMP, LCALL
pc_comb(15 downto 8) <= s_help;
pc_comb(7 downto 0) <= unsigned(rom_data_i);
when "1000" => -- RET, RETI
pc_comb(15 downto 8) <= s_help;
pc_comb(7 downto 0) <= s_reg_data;
when "1001" => -- MOVC_A_ATPC
pc_comb <= pc_plus1 + conv_unsigned(acc,8);
when others => pc_comb <= pc;
end case;
end process p_pc;
------------------------------------------------------------------------------
-- purpose: write RAM, SFR or bitadressable Registers
-- inputs: reset,clk
-- outputs: SFR, gprbit
------------------------------------------------------------------------------
p_write_ram : process (reset,clk)
begin
if reset='1' then
ram_en_o <= '0';
gprbit(0) <= conv_unsigned(0,8);
gprbit(1) <= conv_unsigned(0,8);
gprbit(2) <= conv_unsigned(0,8);
gprbit(3) <= conv_unsigned(0,8);
gprbit(4) <= conv_unsigned(0,8);
gprbit(5) <= conv_unsigned(0,8);
gprbit(6) <= conv_unsigned(0,8);
gprbit(7) <= conv_unsigned(0,8);
gprbit(8) <= conv_unsigned(0,8);
gprbit(9) <= conv_unsigned(0,8);
gprbit(10) <= conv_unsigned(0,8);
gprbit(11) <= conv_unsigned(0,8);
gprbit(12) <= conv_unsigned(0,8);
gprbit(13) <= conv_unsigned(0,8);
gprbit(14) <= conv_unsigned(0,8);
gprbit(15) <= conv_unsigned(0,8);
s_r0_b0 <= conv_unsigned(0,8);
s_r1_b0 <= conv_unsigned(0,8);
s_r0_b1 <= conv_unsigned(0,8);
s_r1_b1 <= conv_unsigned(0,8);
s_r0_b2 <= conv_unsigned(0,8);
s_r1_b2 <= conv_unsigned(0,8);
s_r0_b3 <= conv_unsigned(0,8);
s_r1_b3 <= conv_unsigned(0,8);
p0 <= conv_unsigned(255,8);
sp <= conv_unsigned(7,8);
dpl <= conv_unsigned(0,8);
dph <= conv_unsigned(0,8);
pcon <= conv_unsigned(0,4);
tcon <= (others => (others => '0'));
tmod <= (others => (others => '0'));
tsel <= conv_unsigned(0,8);
p1 <= conv_unsigned(255,8);
scon <= (others => (others => '0'));
s_smodreg <= (others => '0');
sbuf <= (others => (others => '0'));
ssel <= conv_unsigned(0,8);
p2 <= conv_unsigned(255,8);
ie <= conv_std_logic_vector(0,8);
p3 <= conv_unsigned(255,8);
ip <= conv_std_logic_vector(0,8);
psw <= conv_std_logic_vector(0,8);
acc <= conv_unsigned(0,8);
b <= conv_unsigned(0,8);
s_reload <= (others => (others => '0'));
all_wt_en_o <= (others => '0');
s_wt <= (others => (others => '0'));
all_trans_o <= (others => '0');
else
ram_en_o <= '1';
if Rising_Edge(clk) then
all_wt_en_o <= ( others => '0' ); -- default values
all_trans_o <= ( others => '0' );
psw(0) <= s_p;
for i in 0 to C_IMPL_N_TMR-1 loop
tcon(i)(3) <= tcon(i)(3) or ((tcon(i)(2) and s_int1_edge(i)) or
((not tcon(i)(2) and not s_int1_h2(i)) and
not(s_ext1isr_d or s_ext1isrh_d)));
tcon(i)(1) <= tcon(i)(1) or ((tcon(i)(0) and s_int0_edge(i)) or
((not tcon(i)(0) and not s_int0_h2(i)) and
not(s_ext0isr_d or s_ext0isrh_d)));
tcon(i)(5) <= tcon(i)(5) or s_tf0_edge(i);
tcon(i)(7) <= tcon(i)(7) or s_tf1_edge(i);
end loop;
-- update TF1, TF0 and IE1, IE0 in dependance on the IT flags
for i in 0 to C_IMPL_N_SIU-1 loop
scon(i)(0) <= scon(i)(0) or s_ri_edge(i);
scon(i)(1) <= scon(i)(1) or s_ti_edge(i);
end loop;
case s_regs_wr_en is
when "001" => -- inc or dec SP
if (s_intpre='1' and state=FETCH) or s_intpre2='1' then
sp <= sp + conv_unsigned(1,1);
else
case s_command is
when RET | RETI =>
sp <= sp - conv_unsigned(1,1);
when others =>
sp <= sp + conv_unsigned(1,1);
end case;
end if;
when "010" => -- write to ACC
acc <= s_data;
when "011" => -- write to ACC and PSW
acc <= s_data;
psw(7) <= new_cy_i(1);
psw(6) <= new_cy_i(0);
psw(2) <= new_ov_i;
when "100" | "101" =>
case s_regs_wr_en is -- sp register
when "100" =>
if conv_integer(s_adr) = 16#81# then
sp <= s_data;
end if;
when "101" =>
if (s_intpre='1' and state=FETCH) or s_intpre2='1' then
sp <= sp + conv_unsigned(1,1);
else
if s_command = POP then
if (conv_integer(s_adr) = 16#81#) then
sp <= s_data;
else
sp <= sp - conv_unsigned(1, 1);
end if;
else
sp <= sp + conv_unsigned(1, 1);
end if;
end if;
when others => NULL;
end case;
if s_adr(7)='1' then
case conv_integer(s_adr) is -- write one byte of a SFR
when 16#80# => p0 <= s_data;
when 16#82# => dpl <= s_data;
when 16#83# => dph <= s_data;
when 16#87# =>
pcon <= s_data(3 downto 0);
s_smodreg(s_ssel) <= s_data(7);
when 16#88# => tcon(s_tsel) <= std_logic_vector(s_data);
when 16#89# => tmod(s_tsel) <= s_data;
when 16#8A# =>
s_reload(s_tsel) <= s_data; -- tl0
s_wt(s_tsel) <= "00";
all_wt_en_o(s_tsel) <= '1';
when 16#8B# =>
s_reload(s_tsel) <= s_data; -- tl1
s_wt(s_tsel) <= "01";
all_wt_en_o(s_tsel) <= '1';
when 16#8C# =>
s_reload(s_tsel) <= s_data; -- th0
s_wt(s_tsel) <= "10";
all_wt_en_o(s_tsel) <= '1';
when 16#8D# =>
s_reload(s_tsel) <= s_data; -- th1
s_wt(s_tsel) <= "11";
all_wt_en_o(s_tsel) <= '1';
when 16#8E# => tsel <= s_data;
when 16#90# => p1 <= s_data;
when 16#98# => scon(s_ssel) <= std_logic_vector(s_data);
when 16#99# =>
sbuf(s_ssel) <= s_data;
all_trans_o(s_ssel) <= '1';
when 16#9A# => ssel <= s_data;
when 16#A0# => p2 <= s_data;
when 16#A8# => ie <= conv_std_logic_vector(s_data,8);
when 16#B0# => p3 <= s_data;
when 16#B8# => ip <= conv_std_logic_vector(s_data,8);
when 16#D0# =>
psw(7 downto 1) <= conv_std_logic_vector(s_data(7 downto 1),7);
when 16#E0# => acc <= s_data;
when 16#F0# => b <= s_data;
when others => NULL;
end case;
-- write one byte to bitadressable GPR
elsif conv_std_logic_vector(s_adr(7 downto 4),4)="0010" then
gprbit(conv_integer(s_adr(3 downto 0))) <= s_data;
elsif conv_std_logic_vector(s_adr,8)="00000000" then
s_r0_b0 <= s_data; -- write R0 / Bank 0
elsif conv_std_logic_vector(s_adr,8)="00000001" then
s_r1_b0 <= s_data; -- write R1 / Bank 0
elsif conv_std_logic_vector(s_adr,8)="00001000" then
s_r0_b1 <= s_data; -- write R0 / Bank 1
elsif conv_std_logic_vector(s_adr,8)="00001001" then
s_r1_b1 <= s_data; -- write R1 / Bank 1
elsif conv_std_logic_vector(s_adr,8)="00010000" then
s_r0_b2 <= s_data; -- write R0 / Bank 2
elsif conv_std_logic_vector(s_adr,8)="00010001" then
s_r1_b2 <= s_data; -- write R1 / Bank 2
elsif conv_std_logic_vector(s_adr,8)="00011000" then
s_r0_b3 <= s_data; -- write R0 / Bank 3
elsif conv_std_logic_vector(s_adr,8)="00011001" then
s_r1_b3 <= s_data; -- write R1 / Bank 3
else -- write on general purpose RAM
NULL;
end if;
when "110" =>
if ((s_intpre='1' and state=FETCH) or s_intpre2='1') or
(s_command /= ANL_C_BIT and
s_command /= ANL_C_NBIT and
s_command /= MOV_C_BIT and
s_command /= ORL_C_BIT and
s_command /= ORL_C_NBIT) then
if s_adr(7)='1' then
case s_adr(6 downto 3) is -- write only one bit of an SFR
when "0000" =>
p0(conv_integer(s_adr(2 downto 0))) <= s_bdata;
when "0001" =>
tcon(s_tsel)(conv_integer(s_adr(2 downto 0))) <= s_bdata;
when "0010" =>
p1(conv_integer(s_adr(2 downto 0))) <= s_bdata;
when "0011" =>
scon(s_ssel)(conv_integer(s_adr(2 downto 0))) <= s_bdata;
when "0100" =>
p2(conv_integer(s_adr(2 downto 0))) <= s_bdata;
when "0101" =>
ie(conv_integer(s_adr(2 downto 0))) <= s_bdata;
when "0110" =>
p3(conv_integer(s_adr(2 downto 0))) <= s_bdata;
when "0111" =>
ip(conv_integer(s_adr(2 downto 0))) <= s_bdata;
when "1010" =>
case s_adr(2 downto 0) is
when "000" => NULL;
when "001" => psw(1) <= s_bdata;
when "010" => psw(2) <= s_bdata;
when "011" => psw(3) <= s_bdata;
when "100" => psw(4) <= s_bdata;
when "101" => psw(5) <= s_bdata;
when "110" => psw(6) <= s_bdata;
when "111" => psw(7) <= s_bdata;
when others => NULL;
end case;
when "1100" =>
acc(conv_integer(s_adr(2 downto 0))) <= s_bdata;
when "1110" =>
b(conv_integer(s_adr(2 downto 0))) <= s_bdata;
when others => NULL;
end case;
else -- write one bit to bitadressable GP
gprbit(conv_integer(s_adr(6 downto 3)))
(conv_integer(s_adr(2 downto 0))) <= s_bdata;
end if;
else
psw(7) <= s_bdata; -- write CY
end if;
when "111" =>
case s_command is
when DA_A | RLC_A | RRC_A => -- write ACC, CY
acc <= s_data;
psw(7) <= new_cy_i(1);
when DIV_AB | MUL_AB => -- write ACC, B, CY, OV
acc <= s_data;
b <= unsigned(aludatb_i);
psw(7) <= '0';
psw(2) <= new_ov_i;
when others => NULL;
end case;
when others => NULL;
end case;
end if;
end if;
end process p_write_ram;
end rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -