📄 al_unit_spec.vhd
字号:
--------------------------------------------------
-- Model : 8051 Behavioral Model,
-- VHDL Entity mc8051.al_unit.interface
--
-- Author : Michael Mayer (mrmayer@computer.org),
-- Dr. Hardy J. Pottinger,
-- Department of Electrical Engineering
-- University of Missouri - Rolla
--
-- Created at : 09/19/98 20:02:07
--
LIBRARY ieee ;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
LIBRARY mc8051 ;
USE mc8051.cpu_pack.all;
USE mc8051.synth_pack.all;
ENTITY al_unit IS
PORT(
ac : IN std_logic ;
alu_cmd : IN std_logic_vector( 3 DOWNTO 0 ) ;
bit_loc : IN std_logic_vector( 2 DOWNTO 0 ) ;
cpu_rst : IN std_logic ;
cy : IN std_logic ;
data_alu : IN std_logic_vector( 2 DOWNTO 0 ) ;
int_clk : IN std_logic ;
ov : IN std_logic ;
set_ac_ov : IN std_logic ;
set_cy : IN std_logic ;
tmp1 : IN std_logic_vector( 7 DOWNTO 0 ) ;
tmp1_done : IN std_logic ;
tmp2 : IN std_logic_vector( 7 DOWNTO 0 ) ;
use_acc_0 : IN std_logic ;
use_cy : IN std_logic ;
ac_out : OUT std_logic ;
alu_result : OUT std_logic_vector( 7 DOWNTO 0 ) ;
cmp_true : OUT std_logic ;
cy_out : OUT std_logic ;
ov_out : OUT std_logic
);
-- Declarations
END al_unit ;
--
-- VHDL Architecture mc8051.al_unit.spec
--
-- Created:
-- by - mrmayer.UNKNOWN (eceultra20.ece.umr.edu)
-- at - 23:25:29 09/02/98
--
-- Generated by Mentor Graphics' Renoir(TM) 3.0 (Build 110)
--
-- the organization is such:
-- tmp1 and tmp2 contain two data paramaters to be used,
-- tmp1 may be complemented and will then be converted to unsigned (arith1)
-- tmp2 may likely be the acc and will be converted to unsigned (arith2)
-- ctrl lines will cause these two arith's to be added, (or hence subtracted
-- if 2's complement was takes on tmp1) or logically combined.
-- Bit functions may also be performed. Flags changed.
-- A comparison will be made between the answer and arith2.
-- The answer will be output to dest.
-- This all happens before done goes high (one clock cycle after rdy
-- goes high - triggered by tmp1_reg).
-- input ports: alu_cmd(3 DOWNTO 0); data_alu(2 DOWNTO 0);
-- set_cy
-- set_ac_ov
-- use_cy
-- use_old_flags
-- bit_loc (2 DOWNTO 0);
-- cpl_tmp1
-- output ports
-- test_result
-- result (7 DOWNTO 0);
-- ac_out, ov_out, cy_out, wr_out
architecture spec of al_unit is
SIGNAL rdy, rdy_clk, done, done_clk : std_logic;
SIGNAL cy_tmp, ac_tmp, ov_tmp : std_logic;
SIGNAL cy_tmp1 : std_logic;
-- SIGNAL cy_old, ac_old, ov_old : std_logic;
SIGNAL bit_instr : std_logic; -- '1' if its a bit instr
SIGNAL bit1, bit2, bit_ans : std_logic;
SIGNAL tmp1_eq_tmp2, bit_to_insert : std_logic;
SIGNAL tmp1_with_bit : std_logic_vector(7 DOWNTO 0);
-- the parts of answer, separate to get info for ac, cy, ov
SIGNAL add_en, sub_en : std_logic;
SIGNAL arith1_ls, arith2_ls, add_ls : unsigned(4 DOWNTO 0);
SIGNAL arith1_ms, arith2_ms, add_ms : unsigned(3 DOWNTO 0);
SIGNAL add_msb : std_logic;
SIGNAL arith_ans : unsigned(7 DOWNTO 0);
SIGNAL tmp1_7_XOR_tmp2_7 : std_logic;
-- signals for the pre-processing to occur on the temp registers
SIGNAL tmp1_post, tmp2_post : std_logic_vector(7 DOWNTO 0);
SIGNAL tmp1_2, tmp1_3 : unsigned(7 DOWNTO 0);
begin
------------------- BEGIN HANDSHAKING and CONTROL PROCESSING
-- The following are flip - flops
-- rdy is set on a clock edge after it receives tmp1_done
-- rdy_clk <= tmp1_done AND int_clk;
--
-- rdy <= '0' WHEN done = '1' OR cpu_rst = '1' ELSE
-- '1' WHEN rising_edge(rdy_clk) ELSE
-- rdy;
--
-- -- alu_done is set one clock cycle after rdy (delayed just to be safe)
-- done_clk <= rdy AND int_clk;
-- done <= '0' WHEN cpu_rst = '1' ELSE
-- '1' WHEN rising_edge(done_clk) ELSE
-- done;
--
-- alu_done <= done;
-------------- DETERMINE THE ANSWER HERE
-- assign the answer to the output port result
alu_result <= tmp1_post WHEN alu_cmd = pass_tmp1 ELSE
tmp2_post WHEN alu_cmd = pass_tmp2 ELSE
tmp2_post WHEN alu_cmd = rotate ELSE
tmp1_with_bit WHEN bit_instr = '1' ELSE
std_logic_vector(arith_ans);
------------- BEGIN PRE OPERAND PROCESSING
-- first decide to complement the temp1 register
tmp1_2 <= unsigned(NOT tmp1) WHEN std_match(data_alu,t1_cpl_val) ELSE
unsigned(tmp1);
-- second perform any necessay inc / dec
tmp1_3 <= tmp1_2 + 1 WHEN std_match(data_alu,t1_inc_val) ELSE
tmp1_2 - 1 WHEN std_match(data_alu,t1_dec_val) ELSE
tmp1_2;
-- third, decide if need to use cpl, inc/dec, swap, or just plain tmp1
tmp1_post <= tmp1(7 DOWNTO 4) & tmp2(3 DOWNTO 0) WHEN std_match(alu_cmd,xchd1) ELSE
std_logic_vector(tmp1_3) WHEN std_match(alu_cmd,std_alu_data) ELSE
tmp1;
------------- BEGIN BIT STUFF
bit_instr <= '1' WHEN std_match(alu_cmd,"11--") ELSE '0';
-- use a selector to get the corret bit for bit1
bit1 <= cy WHEN use_cy = '1' ELSE
tmp1(0) WHEN bit_loc = "000" ELSE
tmp1(1) WHEN bit_loc = "001" ELSE
tmp1(2) WHEN bit_loc = "010" ELSE
tmp1(3) WHEN bit_loc = "011" ELSE
tmp1(4) WHEN bit_loc = "100" ELSE
tmp1(5) WHEN bit_loc = "101" ELSE
tmp1(6) WHEN bit_loc = "110" ELSE
tmp1(7) WHEN bit_loc = "111" ELSE
'X';
-- bit2 is input to the bit operator, and equal bit1 or /bit1
-- cpl bit1 if cpl_bit_logic
bit2 <= NOT bit1 WHEN std_match(alu_cmd,cpl_bit_logic) ELSE bit1;
-- perform bit operations
bit_ans <= bit2 AND cy WHEN std_match(data_alu,anl_instr) ELSE -- anl instr
bit2 OR cy WHEN std_match(data_alu,orl_instr) ELSE -- orl instr
bit2;
bit_to_insert <= '0' WHEN alu_cmd = clr_bit ELSE
'1' WHEN alu_cmd = set_bit ELSE
bit_ans;
-- figure out where the bit gets inserted
tmp1_with_bit(0) <= bit_to_insert WHEN bit_loc = "000" ELSE tmp1(0);
tmp1_with_bit(1) <= bit_to_insert WHEN bit_loc = "001" ELSE tmp1(1);
tmp1_with_bit(2) <= bit_to_insert WHEN bit_loc = "010" ELSE tmp1(2);
tmp1_with_bit(3) <= bit_to_insert WHEN bit_loc = "011" ELSE tmp1(3);
tmp1_with_bit(4) <= bit_to_insert WHEN bit_loc = "100" ELSE tmp1(4);
tmp1_with_bit(5) <= bit_to_insert WHEN bit_loc = "101" ELSE tmp1(5);
tmp1_with_bit(6) <= bit_to_insert WHEN bit_loc = "110" ELSE tmp1(6);
tmp1_with_bit(7) <= bit_to_insert WHEN bit_loc = "111" ELSE tmp1(7);
tmp1_eq_tmp2 <= '1' WHEN std_match(tmp1_post,tmp2_post) ELSE '0';
cmp_true <= bit_ans WHEN bit_instr = '1' ELSE -- for JB, JNB, JC, JBC, etc.
tmp1_eq_tmp2 WHEN std_match(alu_cmd,compare_1_2) ELSE -- for JZ
NOT tmp1_eq_tmp2; -- for JNZ, DJNZ, CJNE
------------- END BIT STUFF
------------- BEGIN ARITHMATIC & LOGIC
arith1_ls <= unsigned('0' & tmp1(3 DOWNTO 0));
arith2_ls <= unsigned('0' & tmp2(3 DOWNTO 0));
arith1_ms <= unsigned('0' & tmp1(6 DOWNTO 4));
arith2_ms <= unsigned('0' & tmp2(6 DOWNTO 4));
-- FULL ADDER WITH AC, OV, AND CY INFO
-- add first 4 bits and store ac
add_ls <= arith2_ls + arith1_ls;
-- need to complement the ac if it is a subtraction
ac_tmp <= NOT add_ls(4) WHEN std_match(data_alu,t1_cpl_val) ELSE
add_ls(4);
-- add next 3 bits (to get ov info)
add_ms <= (arith2_ms + arith1_ms) + ("000" & add_ls(4));
-- find the msb
tmp1_7_XOR_tmp2_7 <= tmp1(7) XOR tmp2(7);
add_msb <= tmp1_7_XOR_tmp2_7 XOR add_ms(3);
-- find the carry bit
cy_tmp1 <= (tmp1_7_XOR_tmp2_7 AND add_ms(3)) OR
(tmp1(3) AND tmp2(3));
cy_tmp <= NOT cy_tmp1 WHEN std_match(data_alu,t1_cpl_val) ELSE
cy_tmp1;
-- ov represents (carry from bit 6 to 7) XOR (cy);
ov_tmp <= cy_tmp XOR add_ms(3);
---- mmayer is ov correct? I think so.
-- mimic the arithmatic and logic units
arith_ans <= add_msb & add_ms(2 DOWNTO 0) & add_ls(3 DOWNTO 0)
WHEN std_match(alu_cmd ,add_instr) ELSE
unsigned(tmp1_post) AND unsigned(tmp2_post) WHEN std_match(data_alu,anl_instr) ELSE
unsigned(tmp1_post) OR unsigned(tmp2_post) WHEN std_match(data_alu,orl_instr) ELSE
unsigned(tmp1_post) XOR unsigned(tmp2_post) WHEN std_match(data_alu,xrl_instr) ELSE
NOT unsigned(tmp2_post) WHEN std_match(data_alu,cpl_instr) ELSE
unsigned(tmp2_post);
-- need to do mul and div and da
------------- END ARITHMATIC & LOGIC
-- write bits to psw
cy_out <= bit_ans WHEN (bit_instr AND set_cy) = '1' ELSE
cy_tmp WHEN set_cy = '1' ELSE
cy;
ac_out <= ac_tmp WHEN set_ac_ov = '1' ELSE
ac;
ov_out <= ov_tmp WHEN set_ac_ov = '1' ELSE
ov;
-- WHAT IS THIS NEXT LINE FOR? -- mrmayer
-- wr_out <= done;
end architecture spec;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -