⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu_core.txt

📁 UART 的VHDL源代码。可在ISE, Max-Plus II,等开发环境下实现。
💻 TXT
字号:
-- Behavioural model of a simple 8-bit CPU
-- download from: www.fpga.com.cn & www.pld.com.cn

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE work.bv_math.ALL;
USE work.cpu8pac.ALL;

ENTITY cpu IS
        GENERIC(cycle_time : TIME := 200 ns); --must be divisible by 8
        PORT(reset : IN std_logic;
            memrd, memwr : OUT std_logic;
            address : OUT std_logic_vector(11 DOWNTO 0);
            data : INOUT std_logic_vector(7 DOWNTO 0));
END cpu;

ARCHITECTURE version1 OF cpu IS

        --internal clock signal
        SIGNAL clock : std_logic;

BEGIN

        clock_gen : PROCESS
        BEGIN
                clock <= '1','0' AFTER cycle_time/2;
                WAIT FOR cycle_time;
        END PROCESS;

        main_sequence : PROCESS

                VARIABLE inst_reg : BIT_VECTOR(3 DOWNTO 0);
                VARIABLE mar : BIT_VECTOR(11 DOWNTO 0); 
                VARIABLE acca, accb : BIT_VECTOR(7 DOWNTO 0); 
                VARIABLE pc : BIT_VECTOR(11 DOWNTO 0);

        BEGIN

        IF reset = '1' THEN

                --initialisation
                memrd <= '1';
                memwr <= '1';
                pc := (OTHERS => '0');
                address <= (OTHERS => 'Z');
                data <= (OTHERS => 'Z');
                WAIT UNTIL rising_edge(clock);

        ELSE
                --fetch phase
                address <= To_StdlogicVector(pc);
                WAIT FOR cycle_time/4;
                memrd <= '0';   
                WAIT FOR cycle_time/2;  
                memrd <= '1';
                --read instruction
                inst_reg := To_bitvector(data(7 DOWNTO 4));
                --load page address
                mar(11 DOWNTO 8) := To_bitvector(data(3 DOWNTO 0)); 
                --increment program counter
                pc := inc_bv(pc);
                --wait until end of cycle
                WAIT UNTIL rising_edge(clock); 
                --execute
                CASE inst_reg IS
                        WHEN add =>
                        --add and sub use overloaded functions from bv_math package
                                acca := acca + accb;
                        WHEN subr =>
                                acca := acca - accb;
                        WHEN inc =>
                                acca := inc_bv(acca);
                        WHEN dec =>
                                acca := dec_bv(acca);
                        WHEN land =>
                                acca := acca AND accb;
                        WHEN lor =>
                                acca := acca OR accb;
                        WHEN cmp =>
                                acca := NOT acca;
                        WHEN lxor =>
                                acca := acca XOR accb;
                        WHEN lita =>
                                acca := acca;
                        WHEN litb =>
                                acca := accb;
                        WHEN clra =>
                                acca := (OTHERS => '0');
                        WHEN lda|ldb|sta|stb =>
                                address <= To_StdlogicVector(pc);
                                WAIT FOR cycle_time/4;
                                memrd <= '0';   
                                WAIT FOR cycle_time/2;  
                                memrd <= '1';
                                --read page offset address
                                mar(7 DOWNTO 0) := To_bitvector(data);
                                --increment program counter
                                pc := inc_bv(pc);
                                --wait until end of cycle
                                WAIT UNTIL rising_edge(clock);
                                --output address of operand
                                address <= To_StdlogicVector(mar);
                                IF ((inst_reg = lda) OR (inst_reg = ldb)) THEN
                                                WAIT FOR cycle_time/4;
                                                memrd <= '0';   
                                                WAIT FOR cycle_time/2;  
                                                memrd <= '1';
                                                IF inst_reg = lda THEN
                                                        --load accumulator a from bus
                                                        acca := To_bitvector(data);
                                                ELSE
                                                        --load accumulator b from bus
                                                        accb := To_bitvector(data);
                                                END IF;
                                                --wait until end of cycle
                                                WAIT UNTIL rising_edge(clock);                             
                                ELSE 
                                                WAIT FOR cycle_time/8;
                                                IF inst_reg = sta THEN
                                                        --ouput data
                                                        data <= To_StdlogicVector(acca);
                                                ELSE
                                                        --ouput data
                                                        data <= To_StdlogicVector(accb);
                                                END IF;
                                                WAIT FOR cycle_time/8;
                                                memwr <= '0';
                                                WAIT FOR cycle_time/2;
                                                memwr <= '1';
                                                WAIT FOR cycle_time/8; 
                                                data <= (OTHERS => 'Z');
                                                --wait until end of cycle
                                                WAIT UNTIL rising_edge(clock);
                                END IF;
                        WHEN jmp =>
                                address <= To_StdlogicVector(pc);
                                --transfer page address to pc from mar
                                pc(11 DOWNTO 8) := mar(11 DOWNTO 8);         
                                --read in offset address
                                WAIT FOR cycle_time/4;
                                memrd <= '0';   
                                WAIT FOR cycle_time/2;  
                                memrd <= '1';
                                pc(7 DOWNTO 0) := To_bitvector(data);
                                --wait until end of cycle
                                WAIT UNTIL rising_edge(clock);                               
                END CASE;
        END IF;

        END PROCESS main_sequence;

END version1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -