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

2.7电路设计举例

 

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

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

      1、PC模块的设计与实现

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

 

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

  1.  
    module pc_reg(
  2.  
     
  3.  
    input wire clk,
  4.  
    input wire rst,
  5.  
     
  6.  
    output reg[5:0] pc,
  7.  
    output reg ce
  8.  
     
  9.  
    );
  10.  
     
  11.  
    always @ (posedge clk) begin //在时钟信号上升沿触发
  12.  
    if (rst == 1'b1) begin
  13.  
    ce <= 1'b0; //复位信号有效的时候,指令存储器使能信号无效
  14.  
    end else begin
  15.  
    ce <= 1'b1; //复位信号无效的时候,指令存储器使能信号有效
  16.  
    end
  17.  
    end
  18.  
     
  19.  
    always @ (posedge clk) begin //在时钟信号上升沿触发
  20.  
    if (ce == 1'b0) begin
  21.  
    pc <= 6'h00; //指令存储器使能信号无效的时候,pc保持为0
  22.  
    end else begin
  23.  
    pc <= pc + 1'b1; //指令存储器使能信号有效的时候,pc在每个时钟加1
  24.  
    end
  25.  
    end
  26.  
     
  27.  
    endmodule

 

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

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

 

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

  1.  
    module rom(
  2.  
     
  3.  
    input wire ce,
  4.  
    input wire[5:0] addr,
  5.  
    output reg[31:0] inst
  6.  
     
  7.  
    );
  8.  
     
  9.  
    reg[31:0] rom[63:0]; //使用二维向量定义存储器
  10.  
     
  11.  
    always @ (*) begin
  12.  
    if (ce == 1'b0) begin
  13.  
    inst <= 32'h0; //使能信号无效时,给出的数据是0
  14.  
    end else begin
  15.  
    inst <= rom[addr]; //使能信号有效时,给出地址addr对应的指令
  16.  
    end
  17.  
    end
  18.  
     
  19.  
    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文件。

  1.  
    module inst_fetch(
  2.  
     
  3.  
    input wire clk,
  4.  
    input wire rst,
  5.  
    output wire[31:0] inst_o
  6.  
     
  7.  
    );
  8.  
     
  9.  
    wire[5:0] pc;
  10.  
    wire rom_ce;
  11.  
     
  12.  
     
  13.  
    //PC模块的例化
  14.  
    pc_reg pc_reg0(.clk(clk), .rst(rst),
  15.  
    .pc(pc), .ce(rom_ce));
  16.  
     
  17.  
    //指令存储器ROM的例化
  18.  
    rom rom0( .ce(rom_ce), .addr(pc), .inst(inst_o));
  19.  
     
  20.  
    endmodule

 

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

 

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

posted @ 2020-11-26 08:38  erinfeng  阅读(241)  评论(0)    收藏  举报