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

📄 top_lc2.vhd

📁 this a pack include source code for quartus 2. It is an implementation of the LC2. The LC-2 compu
💻 VHD
字号:
-- TOP_LC2 module
--
-- Cyclone - LC2 Implementation
-- Uses VGA to Display Data 
-- SW7 is clock for LC2 - several clocks needed for each instruction
-- SW8 is reset for LC2
--
-- This Module uses UP1core functions and they must be in the user library path
-- or current project directory
-- VHDL synthesis and simulation model of LC-2 machine
-- as described in Appendix C of Introduction to Computing Systems
-- by Yale Patt and Sanjay Patel
--
-- Registers contain register address on reset.  Data memory
-- is initialized to 5555 AAaa for program on reset
-- Use lc2 module to simulate LC2 without video display hardware
--
--
-- UP1PACK - UP1core package
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE  IEEE.STD_LOGIC_ARITH.all;
USE  IEEE.STD_LOGIC_UNSIGNED.all;
LIBRARY lpm;
USE lpm.lpm_components.ALL;
PACKAGE up1core IS
	COMPONENT dec_7seg
		PORT(	hex_digit: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
				segment_a, segment_b, segment_c, segment_d,
				segment_e, segment_f, segment_g : OUT STD_LOGIC);
	END COMPONENT;
	COMPONENT debounce
		PORT(pb, clock_100Hz 	: IN	STD_LOGIC;
	         pb_debounced		: OUT	STD_LOGIC);
	END COMPONENT;
	COMPONENT onepulse
		PORT(pb_debounced, clock: IN	STD_LOGIC;
		 	 pb_single_pulse	: OUT	STD_LOGIC);
	END COMPONENT;
	COMPONENT clk_div
		PORT(clock_25Mhz		: IN	STD_LOGIC;
			clock_1MHz			: OUT	STD_LOGIC;
			clock_100KHz		: OUT	STD_LOGIC;
			clock_10KHz			: OUT	STD_LOGIC;
			clock_1KHz			: OUT	STD_LOGIC;
			clock_100Hz			: OUT	STD_LOGIC;
			clock_10Hz			: OUT	STD_LOGIC;
			clock_1Hz			: OUT	STD_LOGIC);
	END COMPONENT;
	COMPONENT vga_sync
 		PORT(clock_25Mhz, red, green, blue		: IN	STD_LOGIC;
         	red_out, green_out, blue_out		: OUT 	STD_LOGIC;
			horiz_sync_out, vert_sync_out		: OUT 	STD_LOGIC;
			pixel_row, pixel_column		: OUT STD_LOGIC_VECTOR(9 DOWNTO 0));
	END COMPONENT;
	COMPONENT char_rom
		PORT(	clock			: IN	STD_LOGIC;
			character_address	: IN	STD_LOGIC_VECTOR(5 DOWNTO 0);
			font_row, font_col		: IN 	STD_LOGIC_VECTOR(2 DOWNTO 0);
			rom_mux_output			: OUT	STD_LOGIC);
	END COMPONENT;
	COMPONENT keyboard
		PORT(	keyboard_clk, keyboard_data, clock_25Mhz , 
			reset, read				: IN	STD_LOGIC;
			scan_code				: OUT	STD_LOGIC_VECTOR(7 DOWNTO 0);
			scan_ready				: OUT	STD_LOGIC);
	END COMPONENT;
	COMPONENT mouse
		PORT( 	clock_25Mhz, reset 	: IN std_logic;
         		mouse_data			: INOUT std_logic;
        		mouse_clk 			: INOUT std_logic;
        		left_button, right_button : OUT std_logic;
        		mouse_cursor_row, mouse_cursor_column : OUT std_logic_vector(9 DOWNTO 0));       
		END COMPONENT;
END up1core;

LIBRARY IEEE;
USE  IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_ARITH.all;
USE  IEEE.STD_LOGIC_UNSIGNED.all;
LIBRARY lpm;
USE lpm.lpm_components.ALL;
LIBRARY work;
USE work.up1core.all;

ENTITY top_lc2 IS

GENERIC(ADDR_WIDTH: integer := 12; DATA_WIDTH: integer := 1);

   PORT( PB1, PB2, Clock_48Mhz, Switch 							: IN std_logic;
         Red,Green,Blue 							: OUT std_logic;
         Horiz_sync,Vert_sync 						: OUT std_logic);
END top_lc2;

ARCHITECTURE behavior OF top_lc2 IS

   COMPONENT lc2
   		PORT(	clock, reset 	: IN STD_LOGIC;
        PC_out, IR_out 	: OUT STD_LOGIC_VECTOR( 15 DOWNTO 0 );
        MAR_out : OUT STD_LOGIC_VECTOR(15 DOWNTO 0 );
		MDR_out	: OUT STD_LOGIC_VECTOR(15 DOWNTO 0 );
		SR1_out	: OUT STD_LOGIC_VECTOR(15 DOWNTO 0 );
		SR2_out	: OUT STD_LOGIC_VECTOR(15 DOWNTO 0 );
		LC2_BUS_out	: OUT STD_LOGIC_VECTOR(15 DOWNTO 0 );
		BEN_out, WRITE_out : OUT STD_LOGIC;
		CC_out : OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
   END COMPONENT;
 

--Force LC2 clock signal on low skew global clock bus line
   COMPONENT GLOBAL
          PORT (a_in : IN STD_LOGIC;
                a_out: OUT STD_LOGIC);
   END COMPONENT;

   SIGNAL Reset, LC2_clock, clock, Vert_sync_in, BEN_out, WRITE_out : STD_LOGIC;
   SIGNAL PC, IR_out, MAR_out, MDR_out, SR1_out, SR2_out,
		  LC2_BUS_out : std_logic_vector(15 DOWNTO 0);
   SIGNAL CC_out : std_logic_vector(2 DOWNTO 0);

-- Video Display Signals
SIGNAL Red_Data, Green_Data, Blue_Data, Power_On, Rev_video : std_logic;

-- Signals for Video ROM Memory for Pixel Data
SIGNAL char_address				: std_logic_vector(5 DOWNTO 0);
SIGNAL sum_address				: std_logic_vector(6 DOWNTO 0);
SIGNAL col_address, row_address	: std_logic_vector(5 DOWNTO 0);
SIGNAL pixel_col, pixel_row		: std_logic_vector(9 DOWNTO 0);
SIGNAL rom_mux_output			: std_logic;
SIGNAL format_address			: std_logic_vector(5 DOWNTO 0);
SIGNAL format_data				: std_logic_vector(5 DOWNTO 0);


-- Signals for Push buttons
SIGNAL PB1_sync, PB2_sync		: std_logic; 
SIGNAL PB2_debounced, PB1_debounced, PB2_debounced_Sync, 
		PB1_debounced_Sync		: std_logic; 
SIGNAL PB1_single_pulse			: std_logic;
SIGNAL switch_sync			: std_logic;


BEGIN



-- Character Format ROM for Video Display
-- Displays constant format character data
-- on left side of Display area
 format_rom: lpm_rom
      GENERIC MAP ( lpm_widthad => 6,
        lpm_numwords => 60,
        lpm_outdata => "UNREGISTERED",
        lpm_address_control => "REGISTERED",
			-- Reads in mif file for data display format
        lpm_file => "format.mif",
        lpm_width => 6)
      PORT MAP ( inclock => clock_48Mhz, address => format_address, q => format_data);


---------------------------------------------------------------------------------------
-- MIPS structural model - contains processor module interconnections
-- Code for each module is in *.VHD files
--
-- connect the LC2 to other components   
  LC2_1 : LC2
   	PORT MAP (	clock => LC2_clock, 
				reset => reset,
	    	    PC_out => PC,
				IR_out => IR_out,
				MAR_out => MAR_out,
				MDR_out => MDR_out,
				SR1_out => SR1_out,
				SR2_out => SR2_out,
				LC2_BUS_out => LC2_BUS_out,
				BEN_out => BEN_out,
				WRITE_out => WRITE_out,
				CC_out => CC_out );



				--Force LC2 clock signal on low skew global clock bus line
   GBUF: GLOBAL
   	PORT MAP (  a_in => PB1_Single_Pulse,
                a_out => LC2_clock);
				-- Generate VGA sync signals for display
   SYNC: vga_sync
 		PORT MAP(clock_25Mhz => clock, 
				red => red_data, green => green_data, blue => blue_data,	
    	     	red_out => red, green_out => green, blue_out => blue,
			 	horiz_sync_out => horiz_sync, vert_sync_out => vert_sync_in,
			 	pixel_row => pixel_row, pixel_column => pixel_col);
				-- Character Font ROM for Video Display
   CGROM: char_rom
		PORT MAP(clock  => clock_48Mhz, character_address => char_address,
				font_row => pixel_row(3 DOWNTO 1), font_col => pixel_col(3 DOWNTO 1),	
				rom_mux_output => rom_mux_output);
-- Debounce Button: Filters out mechanical bounce for around 64Ms.
-- Debounce clock uses Vert_Sync timing signal (16Ms) to save hardware
-- needed for a clock prescaler
	DB1: debounce
		PORT MAP(pb => pb1, clock_100Hz => vert_sync_in , pb_debounced => pb1_debounced);

				-- Debounce reset pushbutton
	DB2: debounce
		PORT MAP(pb => pb2, clock_100Hz => vert_sync_in , pb_debounced => pb2_debounced);

				-- Output Pushbutton Pulse for 1 25Mhz clock cycle
	SP1: onepulse
		PORT MAP(pb_debounced => pb1_debounced_sync, clock => clock,
		 	 	 pb_single_pulse => pb1_single_pulse);


------------------------------------------------------------------------------

			-- Reset signal for LC2 processor
Reset <=  PB2_Debounced_Sync;

Vert_sync <= vert_sync_in;

			-- Colors for pixel data on video signal
			-- address video_rom for pixel color data
			-- Switch 2 xor Rev_Video will reverse video
Red_Data <= not ((rom_mux_output xor Switch_Sync) xor Rev_video);
Green_Data <= not ((rom_mux_output xor Switch_Sync) xor Rev_video);
Blue_Data <= '1';

			-- current character row and column being displayed
row_address(5 DOWNTO 0) <= pixel_row(9 DOWNTO 4);
col_address(5 DOWNTO 0) <= pixel_col(9 DOWNTO 4);



		-- Address for Constant Character Data Format ROM
format_address(1 DOWNTO 0) <= Col_address(1 DOWNTO 0);
format_address(5 DOWNTO 2) <= Row_address(4 DOWNTO 1);

-- This Process makes a 24Mhz clock using the 48Mhz USB clock
Divide_Clock: PROCESS
BEGIN
  WAIT UNTIL (clock_48Mhz'event) AND (clock_48Mhz='1');
  clock <= not clock;
END PROCESS Divide_Clock;

-- This Process Provides Character Data for Video Display
-- by generating addresses for the Character Generator ROM
-- using the character row address and col address provided by the Video 
-- Sync process  - 40 characters by 30 lines of display area

VIDEO_DISPLAY_DATA: PROCESS
BEGIN
  WAIT UNTIL (clock'event) AND (clock='1');

			-- Reverse Video for Title at top of screen
IF (row_address <= "00011") THEN rev_video <= '1'; 
	ELSE rev_video <= '0';
END IF;

			-- Blank characters on edge of screen and on alternating lines
IF (row_address(0)='0')  OR
   (col_address < "001000") OR (col_address >"010101") 
THEN char_address <= "100000";
ELSE 

			-- Constant Character Area - use data from format ROM
 IF ((col_address >= "001000") AND (col_address <= "001011")) THEN
	 char_address <= format_data;
 ELSE
			-- Couple of Spaces
  IF (col_address = "001100") OR (col_address = "001101") 
			-- Blanks on Top and Bottom line of Display Area  
  OR (row_address < "00010") OR (row_address > "11011")
  THEN char_address <= "100000";
 
  ELSE

			-- Numeric Data From Simulation
			-- Display Values in Hex
  CASE  row_address(4 DOWNTO 1) IS
	WHEN  "0001"  =>
		CASE col_address IS
		-- Print "Computer" on first line of data display area
 	    	WHEN "001110" => 
				char_address <= "000011";
	    	WHEN "001111" => 
				char_address <= "001111" ;
	    	WHEN "010000" => 
				char_address <= "001101" ;
	    	WHEN "010001" => 
				char_address <= "010000" ;
	    	WHEN "010010" => 
				char_address <= "010101" ;
	    	WHEN "010011" => 
				char_address <= "010100" ;
	    	WHEN "010100" => 
				char_address <= "000101" ;
	    	WHEN "010101" => 
				char_address <= "010010" ;
	    	WHEN OTHERS =>
				char_address <= char_address;
        END CASE;
	WHEN  "0010" =>
	    CASE col_address IS
			WHEN "010100" => 
 				-- Selects Hex Character Address with 4-bit value from signal
               char_address <= "11" & PC(7 DOWNTO 4);
        	WHEN "010101" =>
  				-- Selects Hex Character Address with 4-bit value from signal
               char_address <= "11" & PC(3 DOWNTO 0);
            WHEN OTHERS =>
               char_address <= "110000";
        END CASE;
	WHEN  "0011"  =>
			-- Selects Hex Character Address with 4-bit value from signal
	    CASE col_address IS
			WHEN "001110" => 
         		char_address <= "11" & IR_out(15 DOWNTO 12);
	    	WHEN "001111" => 
				char_address <= "11" & IR_out(11 DOWNTO 8);
	    	WHEN "010000" => 
				char_address <= "11" & IR_out(7 DOWNTO 4);
	    	WHEN "010001" => 
				char_address <= "11" & IR_out(3 DOWNTO 0);
	    	WHEN OTHERS =>
				char_address <= "100000";
        END CASE;
	WHEN   "0100"  =>
  			-- Selects Hex Character Address with 4-bit value from signal
	    CASE col_address IS
			WHEN "001110" => 
         		char_address <= "11" & MAR_out(15 DOWNTO 12);
	    	WHEN "001111" => 
				char_address <= "11" & MAR_out(11 DOWNTO 8);
			WHEN "010000" =>
        		char_address <= "11" & MAR_out(7 DOWNTO 4);
        	WHEN "010001" =>
         		char_address <= "11" & MAR_out(3 DOWNTO 0);
        	WHEN OTHERS =>
         		char_address <= "100000";
        END CASE;
	WHEN   "0101"  =>
	    CASE col_address IS
  			-- Selects Hex Character Address with 4-bit value from signal
			WHEN "001110" => 
         		char_address <= "11" & MDR_out(15 DOWNTO 12);
	    	WHEN "001111" => 
				char_address <= "11" & MDR_out(11 DOWNTO 8);
			WHEN "010000" => 
         		char_address <= "11" & MDR_out(7 DOWNTO 4);
        	WHEN "010001" =>
          		char_address <= "11" & MDR_out(3 DOWNTO 0);
        	WHEN OTHERS =>
         		char_address <= "100000";
        END CASE;
	WHEN   "0110"  =>
	    CASE col_address IS
		     WHEN "001110" => 
 			-- Selects Hex Character Address with 4-bit value from signal
         		 char_address <= "11" & LC2_BUS_out(15 DOWNTO 12);
        	 WHEN "001111" => 
                 char_address <= "11" & LC2_BUS_out(11 DOWNTO 8);
        	 WHEN "010000" => 
				 char_address <= "11" & LC2_BUS_out(7 DOWNTO 4);
	    	 WHEN "010001" => 
				 char_address <= "11" & LC2_BUS_out(3 DOWNTO 0);
			 WHEN OTHERS =>
                 char_address <= "100000";
        END CASE;
	WHEN   "0111"  =>
	    CASE col_address IS
			WHEN "001110" => 
  			-- Selects Hex Character Address with 4-bit value from signal
        	  char_address <= "110" & CC_out(2 DOWNTO 0);
        	WHEN OTHERS =>
         	  char_address <= "100000";
        END CASE;
	WHEN   "1000"  =>
	    CASE col_address IS
		     WHEN "001110" => 
 			-- Selects Hex Character Address with 4-bit value from signal
         		 char_address <= "11" & SR1_out(15 DOWNTO 12);
        	 WHEN "001111" => 
                 char_address <= "11" & SR1_out(11 DOWNTO 8);
        	 WHEN "010000" => 
				 char_address <= "11" & SR1_out(7 DOWNTO 4);
	    	 WHEN "010001" => 
				 char_address <= "11" & SR1_out(3 DOWNTO 0);
			 WHEN OTHERS =>
                 char_address <= "100000";
        END CASE;
	WHEN   "1001"  =>
	    CASE col_address IS
		     WHEN "001110" => 
 			-- Selects Hex Character Address with 4-bit value from signal
         		 char_address <= "11" & SR2_out(15 DOWNTO 12);
        	 WHEN "001111" => 
                 char_address <= "11" & SR2_out(11 DOWNTO 8);
        	 WHEN "010000" => 
				 char_address <= "11" & SR2_out(7 DOWNTO 4);
	    	 WHEN "010001" => 
				 char_address <= "11" & SR2_out(3 DOWNTO 0);
			 WHEN OTHERS =>
                 char_address <= "100000";
        END CASE;
	WHEN   "1010"  =>
	    IF col_address = "001110" 
 			-- Select "0" OR "1" character address
        THEN char_address <= "11000" & WRITE_out;
        ELSE
         char_address <= "100000";
        END IF;
	WHEN   "1011"  =>
	    IF col_address = "001110" 
 			-- Select "0" OR "1" character address
        THEN char_address <= "11000" & BEN_out;
        ELSE
         char_address <= "100000";
        END IF;
	WHEN   "1100"  =>
	    IF col_address = "001110" 
 			-- Select Up arrow or Down arrow character address
        THEN char_address <= "0111" & LC2_Clock & "0";
        ELSE
         char_address <= "100000";
        END IF;
	WHEN   "1101"  =>
	    IF col_address = "001110" 
 			-- Select Up arrow or Down arrow character address
         THEN char_address <= "0111" & Reset & "0";
        ELSE
         char_address <= "100000";
        END IF;
	WHEN OTHERS =>
      char_address <= "100000";
  END CASE;
  END IF;
 END IF;
END IF;
END PROCESS VIDEO_DISPLAY_DATA;


	

-- Sync extenal pushbutton inputs to chip clock
PUSH_BUTTON_SYNC: PROCESS 
BEGIN
  	WAIT UNTIL (clock'event) AND (clock='1');
	PB1_Sync <=  PB1;
	PB2_Sync <=  PB2;
	Switch_Sync <= Switch;
	PB1_DEBOUNCED_SYNC <= PB1_DEBOUNCED;
	PB2_DEBOUNCED_SYNC <= PB2_DEBOUNCED;
END PROCESS PUSH_BUTTON_SYNC;


END behavior;

⌨️ 快捷键说明

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