首页 > 代码库 > 自己动手写处理器之第二阶段(4)——电路设计举例

自己动手写处理器之第二阶段(4)——电路设计举例

将陆续上传本人写的新书《自己动手写处理器》(尚未出版),今天是第八篇,我尽量每周四篇

2.7电路设计举例

      本节将设计一个简化的处理器取指令电路,通过这个例子体会Verilog HDL的使用。

      处理器内部一般有一个PC寄存器,其中存储指令地址,正常运行过程中,PC的值会随时间增加,同时从指令存储器中取出对应地址的指令。所以,本节实现的处理器取指令电路,包含两部分:PC模块、指令存储器。

      1、PC模块的设计与实现

      PC模块的功能就是给出取指令地址,同时每个时钟周期取指令地址递增。其接口设计如图2-13所示。采用左边是输入接口,右边是输出接口的方式绘制,这样便于理解。接口作用描述如表2-5所示。



      此处定义指令地址pc的宽度为6,PC模块的主要代码如下,可以参考本书光盘Code\Chapter2目录下的pc_reg.v文件。

module pc_reg(

	input	wire	     clk,
	input  wire	     rst,
	
	output reg[5:0]    pc,
	output reg         ce
	
);

	always @ (posedge clk) begin  //在时钟信号上升沿触发
	   if (rst == 1'b1) begin
		ce <= 1'b0;      //复位信号有效的时候,指令存储器使能信号无效
	   end else begin
		ce <= 1'b1;      //复位信号无效的时候,指令存储器使能信号有效
	   end
	end

always @ (posedge clk) begin  //在时钟信号上升沿触发
	   if (ce == 1'b0) begin
		pc <= 6'h00;     //指令存储器使能信号无效的时候,pc保持为0
	   end else begin
	 	pc <= pc + 1'b1; //指令存储器使能信号有效的时候,pc在每个时钟加1
	   end
	end
	
endmodule

      2、指令存储器ROM的设计与实现

      指令存储器ROM的作用是存储指令,并依据输入的地址,给出对应地址的指令。其接口如图2-14所示,还是采用左边是输入接口,右边是输出接口的方式绘制,这样便于理解。接口描述如表2-6所示。


      此处定义指令的宽度为32,指令存储器ROM的主要代码如下,可以参考在本书光盘Code\Chapter2目录下的rom.v文件。

module rom(

	input  wire          ce,
	input  wire[5:0]	 addr,
	output reg[31:0]	 inst
	
);

	reg[31:0]  rom[63:0];      //使用二维向量定义存储器

	always @ (*) begin
	   if (ce == 1'b0) begin
		inst <= 32'h0;      //使能信号无效时,给出的数据是0
	   end else begin
	       inst <= rom[addr];  //使能信号有效时,给出地址addr对应的指令
	   end
	end

endmodule

      其中使用了一个二维向量定义存储器,深度是64,每个元素的宽度是32,这也是使用6位地址即可的原因。

      3、顶层文件

      先介绍元件例化的知识,在一个复杂电路的实现过程中,可以将其分割成多个功能单元分别实现,然后在一个顶层文件中通过调用各个功能单元,将其按照一定方式连接在一起,从而实现最终电路。其中调用功能单元的过程就称为元件例化。元件例化的格式如图2-15所示。


      经过上面两步,我们分别实现了PC模块、指令存储器ROM,现在可以编写顶层文件将两者连接起来。连接方式如图2-16所示。

     


      PC模块的输出pc连接到指令存储器ROM的地址接口addr,PC模块输出的使能信号ce连接到ROM的使能信号接口ce。顶层模块对应的模块名为inst_fetch,有三个接口,接口描述如表2-7所示。


      inst_fetch模块的主要代码如下,其中例化了PC模块、指令存储器ROM。可以参考本书光盘Code\Chapter2目录下的inst_fetch.v文件。

module inst_fetch(

	input	wire		clk,
	input  wire		rst,
	output wire[31:0]   inst_o
	
);

	wire[5:0] pc;
	wire      rom_ce;
	
 
       //PC模块的例化
	pc_reg pc_reg0(.clk(clk),	.rst(rst),
		        .pc(pc),	.ce(rom_ce));
	
       //指令存储器ROM的例化
       rom rom0( .ce(rom_ce),   .addr(pc),  .inst(inst_o));

endmodule

      PC模块的输出pc、ROM模块的输入addr都连接到变量pc,所以两者连接在一起;PC模块的输出ce、ROM模块的输入ce都连接到rom_ce,所以两者连接在一起。这样就实现了图2-16所示的连接关系。


下一次将介绍如何仿真,未完待续!




自己动手写处理器之第二阶段(4)——电路设计举例