PC取指令的demo


title: VeriogHDL
date: 2019-05-28 15:20:35
tags: verilog
categories: verilog


PC取指令的demo

PC寄存器

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;
    end else begin
        pc<=pc+1'b1;
    end;
end;
endmodule;

ROM

rom.v`

module rom(
    input wire ce,//pc_reg的输出,有效时从rom中取
    input wire[5:0] addr,//pc_reg的输出,指令地址
    output reg[31:0] inst//取出的数据
);
    reg[31:0] rom [63:0]//二重指针相当于64行三十二列,每个但地址里存有32bit数据
    initial $readmemh ( "rom.data", rom );//初始化rom中的数据
always@(*)begin
    if(ce==1'b0)begin//使能信号无效时输出0
            inst <=32'h0;
        end else begin 
            inst <=rom[addr];//使能信号有效时输出地址中的数据,异步
            end
        end
endmodule

取指令单元

inst_fetch.v

module inst_fetch(
    input wire clk,
    input wire rst,
    output wire [31:0] inst_o
);
    wire[5:0] pc;//就是一般意义上的连接线,将pc_reg和rom连在一起
    wire rom_ce;
    pc_reg pc_reg0(.clk(clk),.rst(rst),
                    .pc(pc),.ce(rom_ce));
    rom rom0(.ce(rom_ce),.addr(pc),.inst(inst_o));
endmodule

rom数据

rom.data

00000000
01010101
02020202
03030303
04040404
05050505
06060606
07070707
08080808
09090909
0a0a0a0a
0b0b0b0b
0c0c0c0c
0d0d0d0d
0e0e0e0e
0f0f0f0f
10101010
11111111
12121212
13131313
14141414
15151515
16161616
17171717
18181818
19191919
1a1a1a1a
1b1b1b1b
1c1c1c1c
1d1d1d1d
1e1e1e1e
1f1f1f1f
20202020
21212121
22222222
23232323
24242424
25252525
26262626
27272727
28282828
29292929
2a2a2a2a
2b2b2b2b
2c2c2c2c
2d2d2d2d
2e2e2e2e
2f2f2f2f
30303030
31313131
32323232
33333333
34343434
35353535
36363636
37373737
38383838
39393939
3a3a3a3a
3b3b3b3b
3c3c3c3c
3d3d3d3d
3e3e3e3e
3f3f3f3f

34020020
3403ff00
3404ffff

测试单元

module inst_fetch_tb;

  reg     CLOCK_50;
  reg     rst;
  wire[31:0]    inst;
  
       
  initial begin
    CLOCK_50 = 1'b0;//时钟信号
    forever #10 CLOCK_50 = ~CLOCK_50;//十纳秒后反向,周期二十纳秒
  end
      
  initial begin
    rst = 1'b1;//复位信号
    #195 rst= 1'b0;//195ns后失效,ce会在下一个上升沿变化
    #1000 $stop;//1000ns后结束仿真
  end
       
  inst_fetch inst_fetch0(
        .clk(CLOCK_50),
        .rst(rst),
        .inst_o(inst)   
    );

endmodule
1559030063022.png

你可能感兴趣的:(PC取指令的demo)