Presentation is loading. Please wait.

Presentation is loading. Please wait.

Processador 8 bits de dados e 16 bits de endereço ROM RAM I/O x”0000” ----------- x”3FFF” x”4000” ----------- x”7FFF” x”8000” ----------- x”FFFF” master.

Similar presentations


Presentation on theme: "Processador 8 bits de dados e 16 bits de endereço ROM RAM I/O x”0000” ----------- x”3FFF” x”4000” ----------- x”7FFF” x”8000” ----------- x”FFFF” master."— Presentation transcript:

1 Processador 8 bits de dados e 16 bits de endereço ROM RAM I/O x”0000” ----------- x”3FFF” x”4000” ----------- x”7FFF” x”8000” ----------- x”FFFF” master slave

2 constant data_width:integer := 8; constant addr_width:integer := 16; subtype data_type is integer range 0 to 2** data_width-1 subtype addr_type is integer range 0 to 2** addr_width-1 + outros tipos de dados

3 type bus_slv_in_type is record data : data_type; -- Data in addr : addr_type; -- Address in en : boolean; -- Enable wr : boolean; -- Write end record; type bus_slv_out_type is record data : data_type; -- Data out end record; ------------------------------------------------------ -- RAM (Bus Slave) ----------------------------------------------------- component ram generic ( depth : integer); port ( clk : in std_logic; busi : in bus_slv_in_type; buso : out bus_slv_out_type); end component;

4 library ieee; use ieee.std_logic_1164.all; package proc_pack is ----------------------------------------------------------------------------- -- Data and address width ----------------------------------------------------------------------------- constant data_width : integer := 8; constant addr_width : integer := 16; subtype data_type is integer range 0 to 2 ** data_width - 1; subtype addr_type is integer range 0 to 2 ** addr_width - 1; ----------------------------------------------------------------------------- -- Opcodes ----------------------------------------------------------------------------- -- NOP constant NOPi : data_type := 0; -- No Operation -- Load and store constant LDAi : data_type := 1; -- load from address to accu constant LDCi : data_type := 2; -- load constant to accu constant STAi : data_type := 3; -- store accu to address constant LDXi : data_type := 8; -- load index register with constant constant INCXi : data_type := 9; -- increment index register constant DECXi : data_type := 10; -- decrement index register -- Arithmetic constant ADDi : data_type := 16; -- add data from address to accu constant SUBi : data_type := 17; -- sub data from address from accu constant NOTi : data_type := 18; -- sub data from address from accu constant ANDi : data_type := 19; -- AND data from address with accu constant ORi : data_type := 20; -- OR data from address with accu constant XORi : data_type := 21; -- XOR data from address with accu -- Shift constant SLLi : data_type := 24; -- shift logical left constant SLRi : data_type := 25; -- shift logical right constant ROLi : data_type := 26; -- rotate left constant RORi : data_type := 27; -- rotate right -- Jump constant JMPi : data_type := 32; -- jump to address constant JCi : data_type := 33; -- jump when carry flag is set constant JNCi : data_type := 34; -- jump when carry flag is not set constant JZi : data_type := 35; -- jump when zero flag is set constant JNZi : data_type := 36; -- jump when zero flag is not set ----------------------------------------------------------------------------- -- Memory mapped addresses ----------------------------------------------------------------------------- constant ADDR_LED : addr_type := 0; constant ADDR_SEG : addr_type := 1; constant ADDR_SWITCH : addr_type := 2; ----------------------------------------------------------------------------- -- Processor Flags ----------------------------------------------------------------------------- type flags_type is record c : boolean; -- Carry flag z : boolean; -- Zero flag end record; ----------------------------------------------------------------------------- -- -- Interfaces and Components -- -----------------------------------------------------------------------------

5 ----------------------------------------------------------------------------- -- Bus interface (Master and Slave) ----------------------------------------------------------------------------- type bus_mst_in_type is record data : data_type; -- Data in end record; type bus_mst_out_type is record data : data_type; -- Data out addr : addr_type; -- Address out en : boolean; -- Enable wr : boolean; -- Write end record; type bus_slv_in_type is record data : data_type; -- Data in addr : addr_type; -- Address in en : boolean; -- Enable wr : boolean; -- Write end record; type bus_slv_out_type is record data : data_type; -- Data out end record; type bus_slv_in_vector is array (natural range <>) of bus_slv_in_type; type bus_slv_out_vector is array (natural range <>) of bus_slv_out_type; ----------------------------------------------------------------------------- -- Bus arbiter ----------------------------------------------------------------------------- component arb generic ( slaves : integer); port ( msti : out bus_mst_in_type; msto : in bus_mst_out_type; slvi : out bus_slv_in_vector(0 to slaves - 1); slvo : in bus_slv_out_vector(0 to slaves - 1)); end component; ----------------------------------------------------------------------------- -- Processor (Bus Master) ----------------------------------------------------------------------------- component proc port ( clk : in std_logic; rst : in std_logic; en : in boolean; busi : in bus_mst_in_type; buso : out bus_mst_out_type); end component; ----------------------------------------------------------------------------- -- RAM (Bus Slave) ----------------------------------------------------------------------------- component ram generic ( depth : integer); port ( clk : in std_logic; busi : in bus_slv_in_type; buso : out bus_slv_out_type); end component;

6 ----------------------------------------------------------------------------- -- ROM (Bus Slave) ----------------------------------------------------------------------------- component rom generic ( depth : integer); port ( clk : in std_logic; busi : in bus_slv_in_type; buso : out bus_slv_out_type); end component; ----------------------------------------------------------------------------- -- I/O and peripherals (Bus Slave) ----------------------------------------------------------------------------- type io_in_type is record switch : std_logic_vector(7 downto 0); -- External Switches end record; type io_out_type is record seg_low : std_logic_vector(6 downto 0); -- External 7-segment low seg_high : std_logic_vector(6 downto 0); -- External 7-segment high led : std_logic_vector(7 downto 0); -- External LEDs end record; component io generic ( depth : integer); port ( clk : in std_logic; rst : in std_logic; busi : in bus_slv_in_type; buso : out bus_slv_out_type; ioi : in io_in_type; ioo : out io_out_type); end component; end proc_pack;

7 Processador 8 Bit dados e 16 Bit endereço ROM RAM I/O Arbiter (arb.vhd) bus_mst_in_type -- data bus_mst_out_type -- addr -- data -- en -- wr LEDs Switches bus_slv_in_type -- addr -- data -- en -- wr -- data bus_slv_out_type -- data io_in_type -- switch io_out_type -- led -- seg system.vhd

8 use work.proc_pack.all; entity arb is generic ( slaves : integer := 3); port ( msti : out bus_mst_in_type; msto : in bus_mst_out_type; slvi : out bus_slv_in_vector(0 to slaves - 1); slvo : in bus_slv_out_vector(0 to slaves - 1)); end arb; architecture rtl of arb is begin -- rtl

9 comb : process (msto, slvo) variable slave : integer range 0 to slaves - 1; begin -- process comb -- Check the the upper two address bits, and select a slave case msto.addr / (2 ** (addr_width - 2)) is when 0 => slave := 0; -- ROM : 0x0000 - 0x3FFF when 1 => slave := 1; -- RAM : 0x4000 - 0x7FFF when others => slave := 2; -- I/O : 0x8000 - 0xFFFF end case; -- Drive all slave inputs for i in 0 to slaves - 1 loop slvi(i).data <= msto.data; slvi(i).addr <= msto.addr; slvi(i).en <= msto.en and slave = i; slvi(i).wr <= msto.wr; end loop; -- i -- Drive master inputs msti.data <= slvo(slave).data; end process comb; end rtl;

10 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.macros.all; use work.proc_pack.all; entity system is generic ( -- Adjust the "speed" of the processor here. Specifies the number of -- processor clock cycles per second. TICKS_PER_SECOND : integer := 16); port ( clk : in std_logic; rst : in std_logic; -- I/O -- seven-segment display seg_low : out std_logic_vector(6 downto 0); seg_high : out std_logic_vector(6 downto 0); -- LEDs led : out std_logic_vector(7 downto 0); -- Switches switch : in std_logic_vector(7 downto 0)); end system; architecture str of system is -- Processor tick signal tick : boolean; -- Processor (Bus master) signal msti : bus_mst_in_type; signal msto : bus_mst_out_type; -- ROM, RAM, I/O (Bus slaves) signal slvi : bus_slv_in_vector(0 to 2); signal slvo : bus_slv_out_vector(0 to 2); -- I/O Signals signal ioi : io_in_type; signal ioo : io_out_type; begin -- str ----------------------------------------------------------------------------- -- Clock scaler to slow the processor down ----------------------------------------------------------------------------- scale_clk : process (clk, rst) variable counter : unsigned(log2_ceil(CLK_RATE / TICKS_PER_SECOND) downto 0); begin -- process scale_clk if rising_edge(clk) then counter := counter - 1; if counter(counter'high) = '1' then counter := to_unsigned(CLK_RATE / TICKS_PER_SECOND - 1, counter'length); tick <= true; else tick <= false; end if; if rst = '1' then counter := (others => '0'); tick <= false; end if; end process scale_clk;

11 ----------------------------------------------------------------------------- -- Bus arbiter ----------------------------------------------------------------------------- arb_i: arb generic map ( slaves => 3) port map ( msti => msti, msto => msto, slvi => slvi, slvo => slvo); ----------------------------------------------------------------------------- -- Processor (Bus master) ----------------------------------------------------------------------------- proc_i : proc port map ( clk => clk, rst => rst, en => tick, busi => msti, buso => msto); ----------------------------------------------------------------------------- -- ROM (Bus slave 0) ----------------------------------------------------------------------------- rom_i : rom generic map ( depth => 256) port map ( clk => clk, busi => slvi(0), buso => slvo(0)); ----------------------------------------------------------------------------- -- RAM (Bus slave 1) ----------------------------------------------------------------------------- ram_i : ram generic map ( depth => 256) port map ( clk => clk, busi => slvi(1), buso => slvo(1)); ----------------------------------------------------------------------------- -- I/O module (Bus slave 2) ----------------------------------------------------------------------------- io_i : io generic map ( depth => 32) port map ( clk => clk, rst => rst, busi => slvi(2), buso => slvo(2), ioi => ioi, ioo => ioo); ----------------------------------------------------------------------------- -- I/O signals ----------------------------------------------------------------------------- -- LEDs led <= ioo.led; -- Seven-segment display seg_low <= ioo.seg_low; seg_high <= ioo.seg_high; -- Switches ioi.switch <= switch; end str;

12 entity rom is generic ( depth : integer := 256); port ( clk : in std_logic; busi : in bus_slv_in_type; buso : out bus_slv_out_type); end rom; architecture rtl of rom is -- Define your ROM content here. type mem_type is array (0 to depth - 1) of data_type; constant mem : mem_type := ( -- load increment LDCi, 1, -- store it at 0x4000 STAi, 64, 0, -- show on 7-segment STAi, 128, ADDR_SEG, -- increment with value at 0x4000 ADDi, 64, 0, -- if no carry out repeat at address 5 JNCi, 0, 5, -- turn on LED(7) LDCi, 128, STAi, 128, ADDR_LED, -- endless loop to address 19 JMPi, 0, 19, others => 0); begin -- rtl rom_proc: process (clk) begin -- process ram_proc if rising_edge(clk) then if busi.en then buso.data <= mem(busi.addr mod depth); end if; end process rom_proc; end rtl;

13 library ieee; use ieee.std_logic_1164.all; use work.proc_pack.all; entity ram is generic ( depth : integer := 256); port ( clk : in std_logic; busi : in bus_slv_in_type; buso : out bus_slv_out_type); end ram; architecture rtl of ram is -- RAM storage signal type mem_type is array (0 to depth - 1) of data_type; signal mem : mem_type; -- Temporary read address, required for correct synthesis -- Refer to Xilinx XST User Guide for more information. signal addr, read_addr : integer range 0 to depth – 1; begin -- rtl addr <= busi.addr mod depth; ram_proc: process (clk) begin -- process ram_proc if rising_edge(clk) then if busi.en then if busi.wr then mem(addr) <= busi.data; end if; read_addr <= addr; end if; end process ram_proc; buso.data <= mem(read_addr); end rtl;

14 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.macros.all; use work.proc_pack.all; entity io is generic ( depth : integer); port ( clk : in std_logic; rst : in std_logic; busi : in bus_slv_in_type; buso : out bus_slv_out_type; ioi : in io_in_type; ioo : out io_out_type); end io; architecture rtl of io is -- Registers type reg_type is record ioo : io_out_type; -- registered output buso : bus_slv_out_type; -- registered output end record; -- Signals to registers signal r, rin : reg_type; begin -- rtl ----------------------------------------------------------------------------- -- Combinational logic ----------------------------------------------------------------------------- comb: process (r, busi, ioi) variable v : reg_type; begin -- process comb v := r; --------------------------------------------------------------------------- -- Read access --------------------------------------------------------------------------- if busi.en and not busi.wr then case busi.addr mod depth is when ADDR_LED => v.buso.data := to_unsigned_integer(r.ioo.led); when ADDR_SWITCH => v.buso.data := to_unsigned_integer(ioi.switch); when others => null; end case; end if; --------------------------------------------------------------------------- -- Write access --------------------------------------------------------------------------- if busi.en and busi.wr then case busi.addr mod depth is when ADDR_LED => v.ioo.led := to_unsigned_std_logic_vector(busi.data, 8); when ADDR_SEG => v.ioo.seg_high := int2seg((busi.data / 16) mod 16); v.ioo.seg_low := int2seg(busi.data mod 16); when others => null; end case; end if;

15 --------------------------------------------------------------------------- -- Drive registers and signals --------------------------------------------------------------------------- rin <= v; ioo <= r.ioo; buso <= r.buso; end process comb; ----------------------------------------------------------------------------- -- Registers ----------------------------------------------------------------------------- regs: process (clk, rst) begin -- process regs if rising_edge(clk) then r <= rin; end if; if rst = '1' then r.ioo.seg_low '0'); r.ioo.seg_high '0'); r.ioo.led '0'); end if; end process regs; end rtl;

16 fetch op execute fetch addr_high fetch addr_low Instruções de 1 e 2 Bytes

17 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.macros.all; use work.proc_pack.all; entity proc is port ( clk : in std_logic; rst : in std_logic; en : in boolean; busi : in bus_mst_in_type; buso : out bus_mst_out_type); end proc; architecture rtl of proc is -- Processor states type state_type is (fetch_op, -- Fetch opcode fetch_addr_high, -- Fetch address high part fetch_addr_low, -- Fetch address low part execute); -- Execute operation -- Processor registers type reg_type is record state : state_type; -- Processor state pc : addr_type; -- Program counter opcode : data_type; -- Fetched opcode addr : addr_type; -- Fetched address accu : unsigned(data_width - 1 downto 0); -- Accumulator x : data_type; -- Index register flags : flags_type; -- Flags buso : bus_mst_out_type; -- Registered outputs end record; -- Register signals signal r, rin : reg_type; begin -- rtl ----------------------------------------------------------------------------- -- Combinational Logic ----------------------------------------------------------------------------- comb: process (r, en, busi) -- Variable for register manipulation variable v : reg_type; -- Variable for accu with carry out variable vaccu : unsigned(data_width downto 0); begin -- process comb --------------------------------------------------------------------------- -- Default assignments --------------------------------------------------------------------------- v := r; -- Do not access memory by default v.buso.en := false; -- Do not write by default v.buso.wr := false; if en then -- Access memory v.buso.en := true; -- Address out is mostly program counter value v.buso.addr := r.pc; -- Data out is mostly accumulator value v.buso.data := to_integer(r.accu); -- Program counter is incremented by default v.pc := (r.pc + 1) mod 2**addr_width;

18 --------------------------------------------------------------------------- -- State machine --------------------------------------------------------------------------- case r.state is -- Fetch the opcode when fetch_op => -- store the opcode v.opcode := busi.data; -- and check it case v.opcode is when RORi | DECXi => -- When single byte operation go to execute v.state := execute; -- and halt the program counter v.pc := r.pc; when LDCi | LDXi => -- When two byte operation go to execute v.state := execute; when others => -- otherwise fetch the address v.state := fetch_addr_high; end case; -- Fetch the high part of the address when fetch_addr_high => -- and store it in address register v.addr := busi.data; v.state := fetch_addr_low; -- Fetch the low part of the address when fetch_addr_low => -- combine it with the high part -- and store the result in address register v.addr := to_integer(to_unsigned(r.addr, data_width) & to_unsigned(busi.data, data_width)) -- Put the address on the bus v.buso.addr := v.addr; -- Halt the program counter v.pc := r.pc; -- check the opcode case r.opcode is when STAi => -- write to Memory v.buso.wr := true; when JMPi => -- load the address to programm counter v.pc := v.addr; when JCi => -- load the address to programm counter when carry flag is set if r.flags.c then v.pc := v.addr; end if; when JNCi => -- load the address to programm counter when carry flag is not set if not r.flags.c then v.pc := v.addr; end if; when JZi => -- load the address to programm counter when zero flag is set if r.flags.z then v.pc := v.addr; end if; when JNZi => -- load the address to programm counter when zero flag is not set if not r.flags.z then v.pc := v.addr; end if; when others => null; end case; -- goto execute v.state := execute;

19 -- Execute the instruction when execute => -- check opcode case r.opcode is when LDCi | LDAi => -- Load data to accumulator v.accu := to_unsigned(busi.data, data_width); when LDXi => -- Load data to index register v.x := busi.data; when ADDi => vaccu := '0' & r.accu + to_unsigned(busi.data, data_width + 1); -- Assign to accumulator v.accu := vaccu(data_width - 1 downto 0); -- Assign flags v.flags.c := to_boolean(vaccu(data_width)); v.flags.z := to_integer(v.accu) = 0; when ANDi => -- AND and assign to accumulator v.accu := r.accu and to_unsigned(busi.data, data_width); -- Assign flags v.flags.z := to_integer(v.accu) = 0; when RORi => -- Rotate through carry v.accu := to_std_logic(r.flags.c) & r.accu(data_width - 1 downto 1); v.flags.c := to_boolean(r.accu(0)); when DECXi => -- Decrement index register v.x := (r.x - 1) mod 2 ** data_width; -- Assign flags v.flags.z := v.x = 0; when others => null; end case; -- goto fetch operand v.state := fetch_op; end case; end if; --------------------------------------------------------------------------- -- Drive register in and signals --------------------------------------------------------------------------- rin <= v; buso <= r.buso; end process comb; ----------------------------------------------------------------------------- -- Registers ----------------------------------------------------------------------------- regs: process (clk, rst) begin -- process regs if rising_edge(clk) then r <= rin; end if; if rst = '1' then r.state <= execute; r.pc <= 0; r.opcode <= NOPi; r.accu '0'); r.flags false); end if; end process regs; end rtl;

20 use ieee.std_logic_1164.all; use work.macros.all; use work.proc_pack.all; use work.syslog.all; entity system_tb is generic ( -- length of clock period PERIOD : time := 1 sec / CLK_RATE; -- Time after simulation is terminated DURATION : time := 10 sec; -- Processor ticks per second TICKS_PER_SECOND : integer := CLK_RATE / 2); end system_tb; architecture beh of system_tb is -- UUT component component system generic ( TICKS_PER_SECOND : integer); port ( clk : in std_logic; rst : in std_logic; seg_low : out std_logic_vector(6 downto 0); seg_high : out std_logic_vector(6 downto 0); led : out std_logic_vector(7 downto 0); switch : in std_logic_vector(7 downto 0)); end component; -- UUT signals signal clk : std_logic := '0'; signal rst : std_logic := '1'; signal seg_low : std_logic_vector(6 downto 0); signal seg_high : std_logic_vector(6 downto 0); signal led : std_logic_vector(7 downto 0); signal switch : std_logic_vector(7 downto 0) := (others => '0'); begin -- beh ----------------------------------------------------------------------------- -- UUT instance ----------------------------------------------------------------------------- UUT: system generic map ( TICKS_PER_SECOND => TICKS_PER_SECOND) port map ( clk => clk, rst => rst, seg_low => seg_low, seg_high => seg_high, led => led, switch => switch); ----------------------------------------------------------------------------- -- Generate clock ----------------------------------------------------------------------------- clk <= not clk after PERIOD / 2;

21 ----------------------------------------------------------------------------- -- The test process ----------------------------------------------------------------------------- test: process variable result : integer; begin -- process test -- Generate reset rst <= '1'; wait for 4 * PERIOD; rst <= '0'; -- Wait for LED(7) wait until rising_edge(clk) and led(7) = '1'; -- Terminate simulation syslog_terminate; end process test; ----------------------------------------------------------------------------- -- The time bomb ----------------------------------------------------------------------------- time_bomb: process begin -- process time_bomb -- Wait until the bomb explodes wait for DURATION; -- Give error message and terminate simulation syslog(error, "Program did not finish"); syslog_terminate; end process time_bomb; end beh;

22 LDA 0x1234, X ; Load value from (0x1234 + X) into accu Três passos seguintes: 1.Definir o código de operação em proc_pack.vhd; 2.Se necessário adicionar um novo estado ao proc.vhd 3.Adicionar entradas case em estados do processador constant LDAIXi : data_type := 11; -- load from address + x -- Execute the instruction when execute => -- check opcode case r.opcode is when LDCi | LDAi | LDAIXi => -- Load data to accumulator v.accu := to_unsigned(busi.data, data_width); Ver a próxima página

23 -- Fetch the low part of the address when fetch_addr_low => -- combine it with the high part -- and store the result in address register v.addr := to_integer(to_unsigned(r.addr, data_width) & to_unsigned(busi.data, data_width)); -- Put the address on the bus v.buso.addr := v.addr; -- Halt the program counter v.pc := r.pc; -- check the opcode case r.opcode is when LDAIXi => -- add x to the address and put it on the bus v.buso.addr := v.addr + r.x; when STAi => -- write to Memory v.buso.wr := true;


Download ppt "Processador 8 bits de dados e 16 bits de endereço ROM RAM I/O x”0000” ----------- x”3FFF” x”4000” ----------- x”7FFF” x”8000” ----------- x”FFFF” master."

Similar presentations


Ads by Google