基于fpga的处理器核心电路设计

这篇博文详细总结了使用FPGA设计一个基本处理器核心的过程。实验包括多个寄存器、多路选择器、加减法单元、计数器和控制单元。处理器通过时钟信号和控制单元操作寄存器,数据通过多路复用器在总线上传输。控制单元在每个时钟周期执行不同操作,支持mvi、mov、add、sub四条指令。整个设计被划分为七个模块,其中寄存器模块由D触发器构成。
摘要由CSDN通过智能技术生成

最近因为导师要求我带大三学生的fpga实验课,有一个实验是用fpga设计处理器的核心电路。做出来以后便用这篇博文总结一下。

该实验只设计了一个最基本的处理器其中包括多个寄存器,一个多路选择器,一个加法/减法单元,计数器和一个控制单元。

寄存器的作用是存储单个位或者字,通过时钟信号和控制单元输出的信号来控制寄存器的输出。处理器所处理的输入数据通过多路复用器加载到不同的寄存器中,复用器的输出称为总线,总线是容许数据从一个位置传到另外一个位置的。该实验寄存器的位宽为16位,总共定义了R0-R7,A,G,IR寄存器。

加减法单元是通过多路复用器将数据首先加载到一个特定的寄存器A中,这个寄存器固定作为这个单元的一个操作数。第二个操作书通过总线传到另外一个数据接口,通过运算操作后,把数据寄存到寄存器G中,寄存器G中的数值可以通过复用器传输到其他位置。

在控制单元的控制下,每个时钟周期可以完成不同的操作,它能控制哪个寄存器加载总线上的数据,哪个寄存器的数值放到总线上。

本次实验需要用到4条指令,mvi,mov,add,sub。每个指令运行的周期如下:

      

通过iR寄存器来查询指令。因为iR寄存器有16位,可以选择前八位来代表指令,后面8位分别代表寄存器,如iiiiiiiixxxxyyyy,iiiiiiii代表指令,xxxx代表Rx寄存器,yyyy代表Ry寄存器。

因此,我们在进行编写程序时,可以把整个实验分为七个模块。

首先是寄存器模块,此处便是一个D触发器。

entity regn is
  port(
	clk,nin,rst<span style="white-space:pre">	</span>: in std_logic;
	n 		: in std_logic_vector(15 downto 0);
	nout 		: out std_logic_vector(15 downto 0)
	);
end regn;

architecture arch of regn is 
  begin
	process(clk,nin,rst)
	  begin
	<span style="white-space:pre">	</span>if(clk'event and clk = '1')
		  then
			if(rst = '0')
			  then
				nout <= "0000000000000000";
			else
			  if(nin = '1')
				then
				  nout <= n;
			  end if;
			end if;
	<span style="white-space:pre">	</span>end if;
	end process;
end arch;
第二个模块是加减法。

entity addsub is
  port(
<span style="white-space:pre">	</span>A,BusWires  : 	in std_logic_vector(15 downto 0);
	G	    : 	out std_logic_vector(15 downto 0);
	clk         : 	in std_logic;
	Add_Sub,Gin : 	in std_logic
<span style="white-space:pre">	</span>);
end addsub;

architecture arch of addsub is
  begin
<span style="white-space:pre">	</span>process(clk,Gin,Add_Sub)
	  begin
		if(clk'event and clk = '1')
		  then
			if(Gin = '1')
			  then
				if(Add_Sub = '1')
				  then
					G <= A+BusWires;
				else
					G <= A-BusWires;
				end if;
			end if;
		end if;
	end process;
end arch;
第三个是多路选择器模块。

<span style="font-size:10px;">entity mul is
  port(
	R0,R1,R2,R3,R4,R5,R6,R7,G,Din	: 	in std_logic_vector(15 downto 0);
	Rout 				: 	in std_logic_vector(7 downto 0);
	Dinout,Gout			:  in std_logic;
	BusWires 			: 	out std_logic_vector(15 downto 0)
	);
end mul;

architecture arch of mul is
  begin
	process(Gout,Dinout,Rout)
	  begin
		case ( Gout & Dinout & Rout) is
			when "0000000001" => BusWires <= R0;
			when "0000000010" => BusWires <= R1;
			when "0000000100" => BusWires <= R2;
			when "0000001000" => BusWires <= R3;
			when "0000010000" => BusWires <= R4;
			when "0000100000" => BusWires <= R5;
			when "0001000000" => BusWires <= R6;
			when "0010000000" => BusWires <= R7;
			when "0100000000" => BusWires <= Din;
			when "1000000000" => BusWires <= G;
			when OTHERS	=> NULL;
		end case;
	end process;
end arch;</span><span style="font-size:18px;">
</span>
第四个模块是加法计数器模块,是进行指令的加减周期计算的。
<pre name="code" class="plain">entity upcount is 
  port(
	rst,clear,clk :     in std_logic;
	Q 	      :     out std_logic_vector(1 downto 0)
		);
end upcount;

architecture arch of upcount is
  signal Q1 	: std_logic_vector(1 downto 0);
  begin
	process(clk)
	  begin
		if(clk'event and clk = '1')
		  then
			if(rst = '0')
			  then
				Q1 <= "00";
			else if(clear = '1')
			  then
				Q1 <= "00";
			else
				Q1 <= Q1 + '1';
			    end if;
			end if;
		end if;
	<span style="white-space:pre">	</span>Q <= Q1;
	end process;
end arch;

 
<span style="font-size:18px; font-family: Arial, Helvetica, sans-serif;">	</span><span style="font-size:18px; font-family: Arial, Helvetica, sans-serif;">第五个模块是38译码器模块,对iR寄存器的输出进行译码从而选择寄存器。</span>
entity dec3to8 is
  port(
	rst	:	in std_logic;
	sel	:	in std_logic_vector(2 downto 0);
	r_out	:	out std_logic_vector(7 downto 0)
	);
end dec3to8;

architecture arch of dec3to8 is
  begin
	process(rst,sel)
	  begin
		if(rst = '0')
		  then
			r_out <= "00000000";
		else
		  case(sel) is
			when "000"	=> <span style="white-space:pre">	</span>r_out <=	"00000001";
			when "001"	=>	r_out <=	"00000010";
			when "010"	=>	r_out <=	"00000100";
			when "011"	=>	r_out <=	"00001000";
			when "100"	=>	r_out <=	"00010000";
			when "101"	=>	r_out <=	"00100000";
			when "110"	=>	r_out <=	"01000000";
			when "111"	=>	r_out <=	"10000000";
			when others => r_out <= "00000000";
		  end case;
		end if;
	end process;
end arch;
第六个模块是处理器模块,是对他所接收的输入进行处理从而选择哪个模块进行输入和输出。

<span style="font-size:10px;">entity control is
  port(
	count 			: in std_logic_vector(1 downto 0);
	reg_IR			: in std_logic_vector(15 downto 0);		
	Rin,Rout		: out std_logic_vector(7 downto 0);		
	IRin,Ain,Gin,Gout,
	DINout,ADDSUB,Clear	: out std_logic;
	Done			: buffer std_logic
	);
end control;

architecture arch of control is
	constant mv 	:std_logic_vector 	:= "00000000";
	constant mvi	:std_logic_vector	:= "00000001";
	constant add	:std_logic_vector	:= "00000010";
	constant sub	:std_logic_vector	:= "00000011";
	constant D	:std_logic_vector	:= "1000";
	constant R0	:std_logic_vector	:= "0000";
	constant R1	:std_logic_vector	:= "0001";
	constant R2	:std_logic_vector	:= "0010";
	constant R3	:std_logic_vector	:= "0011";
	constant R4	:std_logic_vector	:= "0100";
	constant R5	:std_logic_vector	:= "0101";
	constant R6	:std_logic_vector	:= "0110";
	constant R7	:std_logic_vector	:= "0111";
	signal w	:std_logic_vector(7 downto 0);
	signal Xreg,Yreg:std_logic_vector(7 downto 0);
 
component dec3to8
	port(
		rst	:	in std_logic;
		sel	:	in std_logic_vector(2 downto 0);
		r_out	:	out std_logic_vector(7 downto 0)
		);
end component;
  begin
	w <= reg_IR(15 downto 8);
	decx	:	dec3to8
	port map('1',reg_IR(6 downto 4),Xreg);
	decy	:	dec3to8
	port map('1',reg_IR(2 downto 0),Yreg);
	process(count,w,Xreg,Yreg)
	  begin
		Rout		<= "00000000";
		Rin		<= "00000000";
		Ain		<= '0';
		Gin		<=	'0';
		ADDSUB	<= '0';
		Gout		<= '0';
		DINout	<= '0';
		Done		<= '0';
		Clear		<=	'0';
		if(count = "00")
		  then
			Rout		<= "00000000";
			Rin		<= "00000000";
			IRin		<= '1';     
			Ain		<= '0';
			Gin		<=	'0';
			ADDSUB	<span style="white-space:pre">	</span><= '0';
			Gout		<= '0';
			DINout	<span style="white-space:pre">	</span><= '0';
			Done		<= '0';
			Clear		<=	'0';
		elsif(count = "01")			
		  then
			if(w = mv)
			  then
				IRin		<=	'0';		
				Ain		<=	'0';
				DINout	<span style="white-space:pre">	</span><=	'0';
				Gout		<= <span style="white-space:pre">	</span>'0';
				Rout		<= <span style="white-space:pre">	</span>Yreg;
				Rin		<=	Xreg;
				Clear		<=	'1';
				Done		<=	'1';
			elsif(w = mvi)
			  then
				IRin		<=	'0';		
				Ain		<=	'0';
				DINout	<span style="white-space:pre">	</span><=<span style="white-space:pre">	</span> '1';
				Gout		<=<span style="white-space:pre">	</span> '0';
				Rout		<= <span style="white-space:pre">	</span>"00000000";
				Rin		<= <span style="white-space:pre">	</span>Xreg;
				Clear		<=	'1';
				Done		<=	'1';
			elsif(w = add)
			  then
				IRin		<=	'0';		
				Ain		<=	'1';
				Gout		<=	'0';
				Done		<=	'0';
				Rin		<=	"00000000";
				Rout		<= Xreg;
				DINout	<=	'0';
				Clear		<=	'0';
			elsif(w = sub)
			  then
				IRin		<=	'0';	
				Ain		<=	'1';
				Gout		<=	'0';
				Done		<=	'0';
				Rin		<=	"00000000";
				Rout		<=	Xreg;
				DINout	<span style="white-space:pre">	</span><=	'0';
				Clear		<=	'0';
			else
			  if(Done = '1')
				then
				  IRin 	<=	'1';
			  else
				IRin	<=	'0';
			  end if;
			end if;
				
		elsif(count = "10")
		  then
			if(w = add)
			  then
				Ain		<= <span style="white-space:pre">	</span>'0';
				Gin		<=	'1';
				Rout		<=	Yreg;
				Gout		<=	'0';
				DINout	<span style="white-space:pre">	</span><=	'0';
				ADDSUB	<span style="white-space:pre">	</span><=	'1';
				Done		<=	'0';
			elsif(w = sub)
			  then
				Ain		<=	'0';
				Gin		<=	'1';
				Rout		<=	Yreg;
				Gout		<=	'0';
				DINout	<=	'0';
				ADDSUB	<=	'0';
				Done		<=	'0';
			else
				IRin		<=	'0';
			end if;
		elsif(count = "11")
		  then
			if(w = add)
			  then
				Rin		<=	Xreg;
				Gin		<=	'0';
				Rout		<=	"00000000";
				Gout		<=	'1';
				Done		<= <span style="white-space:pre">	</span>'1';
				Clear		<=	'1';
				DINout	<span style="white-space:pre">	</span><=	'0';
			elsif(w = sub)
			  then
				Rin		<=	Xreg;
				Gin		<=	'0';
				Rout		<=	"00000000";
				Gout		<=	'1';
				Clear		<=	'1';
				DINout	<span style="white-space:pre">	</span><=	'0';
				Done		<=<span style="white-space:pre">	</span> '1';
			else
				Rin		<= "00000000";
				Rout		<= "00000000";
				IRin		<=	'0';
		<span style="white-space:pre">	</span>end if;
						
		end if;
	end process;
end arch;		</span>
第七个模块就是把所有模块进行例化和调用。

entity processor is
  port(
	Clk,rst	<span style="white-space:pre">	</span>: 	in std_logic;	
	BusWire		: <span style="white-space:pre">	</span>out std_logic_vector(15 downto 0);
	Done		: <span style="white-space:pre">	</span>out	std_logic;
	Din		:	in std_logic_vector(15 downto 0)
	);
end processor;
	
architecture arch of processor is
	signal 	reg0,reg1,reg2,reg3,reg4,reg5,
		reg6,reg7,regG,buswr,rega,regIR		: 	std_logic_vector(15 downto 0);
	signal	IRin,Ain,Gin,Gout,
		DINout,ADD_SUB,Clear			: 	std_logic;
	signal 	reg,Rout,Rin				:	std_logic_vector(7 downto 0);
	signal	upcount_1				:	std_logic_vector(1 downto 0);

-- register
component regn
	port(
		clk,nin,rst	: 	in std_logic;
		n 		: 	in std_logic_vector(15 downto 0);
	<span style="white-space:pre">	</span>nout 		: 	out std_logic_vector(15 downto 0)
	);
end component;

-- multiplexers  : select the register
component mul
	port(
		R0,R1,R2,R3,R4,R5,R6,R7,G,Din	: 	in std_logic_vector(15 downto 0);
		Rout 				: 	in std_logic_vector(7 downto 0);
		Dinout,Gout			:  in std_logic;
		BusWires 			: 	out std_logic_vector(15 downto 0)
		);
end component;

-- addsub
component addsub
	port(
		A,BusWires 	: 	in std_logic_vector(15 downto 0);
		G 		: 	out std_logic_vector(15 downto 0);
		clk     	: 	in std_logic;
		Add_Sub,Gin 	: 	in std_logic
		);
end component;

--control unit
component control
	port(
			count 			: in std_logic_vector(1 downto 0);
			reg_IR			: in std_logic_vector(15 downto 0);
			Rin,Rout		: out std_logic_vector(7 downto 0);
			IRin,Ain,Gin,Gout,
			DINout,ADDSUB,Clear<span style="white-space:pre">	</span>: out std_logic;
			Done			: buffer std_logic
		);
end component;

--upcount 
component upcount
	port(
			rst,clear,clk <span style="white-space:pre">	</span>  : 	in std_logic;
			Q 		  :     out std_logic_vector(1 downto 0)
		);	
end component;
<span style="white-space:pre">	</span>begin
		
		R0<span style="white-space:pre">	</span>:	regn
		port map(clk,Rin(0),rst,buswr,reg0);
		
		R1	:	regn
		port map(clk,Rin(1),rst,buswr,reg1);
		
		R2	:	regn
		port map(clk,Rin(2),rst,buswr,reg2);
		
		R3	:	regn
		port map(clk,Rin(3),rst,buswr,reg3);
		
		R4	:	regn
		port map(clk,Rin(4),rst,buswr,reg4);
		
		R5	:	regn
		port map(clk,Rin(5),rst,buswr,reg5);
		
		R6	:	regn
		port map(clk,Rin(6),rst,buswr,reg6);
		
		R7	:	regn
		port map(clk,Rin(7),rst,buswr,reg7);
		
		A	:	regn
		port map(clk,Ain,rst,buswr,rega);
		
		IR	:	regn
		port map(clk,IRin,rst,Din,regIR);
		
		Add	:	addsub
		port map(rega,buswr,regG,clk,Add_sub,Gin);
		
		multi	: mul
		port map(reg0,reg1,reg2,reg3,reg4,reg5,reg6,reg7,regG,Din,
					Rout,DINout,Gout,buswr);
					
		count	:	upcount
		port map(rst , Clear , clk,upcount_1);
		
		control_unit	:	control
		port map(upcount_1,regIR,Rin,Rout,IRin,Ain,Gin,
			Gout,DINout,ADD_SUB,Clear,Done);

		BusWire <= buswr;
		
end arch;
	
	<span style="font-size:18px;">在testbeech中给定的激励如下</span>
<pre name="code" class="plain">clk_gen	:process
begin
	clk <= '0';
	wait for clk_period / 2;
	clk <= '1';
	wait for clk_period / 2;
end process;

rst_gen	:process
begin
	rst	<=	'0';
	wait for clk_period * 3;
	rst	<= '1';
	wait;
end process;

Din_gen	:process
begin
	Din <= "0000000100101000";
	wait for clk_period * 4;
	Din <= "0000011111011110";
	wait for clk_period;
	Din <= "0000000101111000";
	wait for clk_period;
	Din <= "0000000111110101";
	wait for clk_period;
	Din <= "0000000000110111";
	wait for clk_period * 2;
	Din <= "0000001000100111";
	wait for clk_period * 4;
	Din <= "0000001100100110";
	wait for clk_period * 4;
	Din <= "0000000100101000";
	wait for clk_period;
	Din <= "0000011111011110";
wait;	
end process;<span style="font-family: Arial, Helvetica, sans-serif;">		</span><span style="font-family: Arial, Helvetica, sans-serif;">	</span>

 
 
在modelsim仿真的波形如下 


另:本人可承接各种毕业设计,pcb设计,FPGA项目设计,电机驱动板卡设计,ARM驱动项目

quincybing 2014.10.28 first version


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值