hdl 简单设计举例

来源:互联网 发布:海尔电视电视直播软件 编辑:程序博客网 时间:2024/05/23 21:28

电路设计举例

       本节设计一个简化的处理器取指令,体会HDL的使用:

       处理器一般有一个PC寄存器,其中存储指令地址,本次尝试包括两个部分:PC模块,指令存储器。

1、 PC模块的设计与实现

PC模块的功能就是给出取指令地址,同时每个时钟周期取指令地址递增。

 

1、 rst 宽度为1 输入 作用为复位信号

2、 clk 宽度为1 输入 作用为时钟信号

3、 pc 宽度为6 输出 作用为要读取的指令地址

4、 ce 宽度为1 输出 指令存储器使能信号。

源码件文件夹的另一个编辑文件

      

       modulepc_reg(

                    

       inputwire                    clk,

       inputwire                    rst,

       outputreg[5:0]      pc,

       outputreg                   ce

);

       always@ (posedge clk) begin            //在时钟上升沿触发

              if(ce ==1'b0) begin

                     pc<= 6'h00                               //指令存储器使能信号无效的时候,pc保持为0

              endelse begin

                     pc<= pc + 1b'1;                 //指令存储器使能信号有效的时候,pc在每个时钟加一

                     end

              end

             

       always@ (posedge clk) begin

              if(rst== 1'b1) begin                   //复位信号有效的时候,指令存储器使能信号无效

                     ce<= 1'b0;                                //

              endelse begin                                  //

                     ce<= 1'b1;                                //复位信号有效的时候,指令存储器使能信号有效

                     end

              end

             

endmodule

 

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

其作用是用来存储指令,并依据输入的地址,给出对应地址的指令模块存在三个接口:addr ce 和 inst

1、 ce     宽度为1,作为输入,作用是使能信号

2、 addr   宽度为6,作为输入接口,作用是要读取的指令地址

3、 inst     宽度为32 用作输出,    作用是读出的指令。

此处定义的指令的宽度为32位,指令存存储器ROM的主要代码如下,

 

module rom(

      

       inputwire                    ce,

       inputwire[5:0]              addr,     

       outputreg[31:0]    inst

);

             

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

      

       initial$readmenh("rom.data",rom);

      

       always@ (*)begin

              if(ce== 1'b0) begin                          //使能无效信号是,给出的数据是零。

                     inst<= 32'h0;

              endelse begin

                     inst<= rom[addr];                     //使能有效信号时,给出地址sddr对应的指令

              end

       end

endmodule

 

3.顶层文件

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

              <模块名><实例名>(

              .<相连的端口名>(相连的信号名),

              .<相连的端口名>(相连的信号名),

 

)

下面为元件例化的例子:

 

module inst_fetch(

             

              inputwire                    clk,

              inputwire                    rst,

              output    wire[31:0]       inst_o

);

 

 

       wire[5:0]pc;

       wire rom_ce;

      

       //PC模块的例化

       pc_regpc_reg0(.clk(clk),       .rst(rst),

                                   .pc(pc),    .ce(rom_ce)

                                   );

                                  

       //指令存储器的例化

       romrom0(.ce(rom_ce), .addr(pc),       .inst(inst_o));

      

endmodule

 

仿真

       仿真思路:给出一个时钟信号。上述电路会在每个时钟信号上升沿将取地址加一,同时从指令存储器中取一条指令。观察取址地址是否加一。遇到的问题:

1、 如何在指令存储器中存储指令,也就是指令存储器的初始化问题。

2、 如何给出时钟信号。

在这里使用ModelSim进行仿真。

系统函数:

       ·初始化存储器由两种方法,一种是对存储器中每个存储单元依次给出初值,就像下面这样:

       Rom[0]=32’h00000000;//存储器rom的第0个元素初始化为0x00000000

       Rom[0]=32‘h01010101;//存储器rom的第0个元素初始化为0x00000000

       ………

       另外一种方法是使用系统函数$readmemh,这样也是更方便的,但是这样也只能用在仿真当中。

       除了$readmemh,HDL还有其他的系统函数,下面举一些例子

       $time显示当前仿真的时间

       $display显示信号的值的函数

       $stop      暂停仿真过程的函数

       $finish    结束仿真过程的函数

 

       $stop用于对仿真过程进行控制,暂停仿真,格式如下:

       $stop();                 //不带参数

       $stop(n)                //n=0:不输出任何信息

                                   //n=1;给出仿真时间和位置

                                   //n=2;给出仿真时间和位置,还有其他一些统计信息

       $readmenh   

              用于读取文件,就像下面这样

              Reg[31:0]rom[63:0];

              Initial$readmenh(“rom.dat”,rom)  //     读取文件的数据到rom当中

 

 

0 0
原创粉丝点击