fpga_feixiang 发表于 2019-1-25 13:45:18

简易CPU的设计和实现02

五.各个部件的代码实现

  1.PC部件的代码实现

module pc (clock,reset,en,pc);
input clock, reset, en;
output reg pc;

wire pc_next;                     //欲寻址的下一条指令

//always过程快
always@ (posedge clock or posedge reset)
begin
if(reset)                              //系统复位,pc清0
      pc <= 0;
else
      if(en)                           //如果使能pc模块,则将下一条指令付给pc端口输出
            pc <= pc_next;
      else
            pc <= pc;                  //否则,pc保持即不工作
end

//assign持续赋值语句
assign pc_next = pc + 1;               //本处理器中下一条指令的地址为当前地址加1
endmodule
&nbsp; &nbsp;2.存储器(Memory)的代码实现

&nbsp;&nbsp;

module memory (clock,reset,addr,din,dout,wr,rd);

input clock;       //时钟信号线
input reset;       //复位信号,高电平有效
input addr;//存储器地址
input din;   //数据线输入
output reg dout;//数据线输出
input wr;          //写使能端,高电平有效
input rd;          //读使能端,高电平有效

reg mem ;//内部的存储空间

always @(posedge clock or posedge reset) begin
        if (reset) begin
          mem <= 'b00001011;      //LDA 01011
          mem <= 'b01001100;      //ADD 01100
          mem <= 'b00101101;      //STA 01101
          mem <= 'b00001011;      //LDA 01011
          mem <= 'b10001100;      //AND 01100
          mem <= 'b00101110;      //STA 01110
          mem <= 'b00001011;      //LDA 01011
          mem <= 'b01101100;      //SUB 01100
          mem <= 'b00101111;      //STA 01111
          mem <= 'b10100000;      //HLT
          mem <= 'b00000000;
          mem <= 'b10010101;
          mem <= 'b01100101;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
          mem <= 'b00000000;
               
               
        end
        else begin
           if (wr)
              mem <= din;
           if (rd)
              dout <= mem ;               
        end
end
endmodule
&nbsp; 3.指令解码器(Idec)的代码实现

module idec (
       clock,   //时钟端口
       reset,   //复位端口
       en,      //译码使能端口
       instruction,//指令输入端口
       opcode,       //操作吗输入端口
       addr,         //存储器地址输入端口
        );

input clock,reset,en;
input instruction;
output reg opcode;
output reg addr;

always @(posedge clock or posedge reset) begin
        if (reset) begin
          opcode <= 0;
          addr <= 0;
                // reset               
        end
        else if (en) begin
          opcode <= instruction ;
          addr <= instruction ;
               
        end
end
endmodule
4.算术逻辑单元(ALU)的代码生成:

module alu (
      clock,      //时钟端口
      reset,      //复位端口
      en,         //alu使能端口
      a,          //累加器输出寄存器
      din,      //操作数1输入   
      n,          //负标志
      z,          //0标志
      c,          //输出进位标志
      v,          //输出溢出标志
      add_en,   //加法使能运算
      sub_en,   //减法使能运算
      and_en,   //与运算
      pass_en,    //使din直通累加器A,不做运算(部分运算需要)
        );

input clock,reset,en,add_en,sub_en,and_en,pass_en;
input din;
output n,z,c,v;
output reg a;
reg c;

always @(posedge clock or posedge reset)
        if (reset) begin
                a <= 0;      //复位累加器清0,
                c <= 0;
                // reset       
        end
        else begin
                if(en) begin
                        if(add_en)
                          {c,a} <= a + din;
                        else if(sub_en)
                          {c,a} <= a - din;
                        else if(and_en)
                          a <= a & din;
                        else if(pass_en)
                          a <= din;
                end
        end


assign z = (a == 8'b0) ? 1: 0 ;    //0标志,如果累加器为0,z=1
assign n = (c == 1) ? 1: 0 ;       //负数标志,如果借位为1,则n=1
assign v = ((a>127) || (a<-128) ? 1:0 );//溢出标志

endmodule
5.控制单元(Control)的代码实现:

module control (
       input clock,
       input reset,         //异步复位端端口
       output reg s0,       //分别作用各阶段的使能信号个端口
       output reg s1,
       output reg s2,
       output reg s3,
       output reg s4,
       output reg s5,
       output reg addrsel,   //选择程序的地址或者选择数据的地址
       output reg instr_add, //加法端口使能信号,以下类似
       output reg instr_sub,
       output reg instr_and,
       output reg instr_pass,
       input opcode    //解码器解码后将指令码传给控制器
        );

parameter LDA = 3'b000, STA = 3'b001, ADD = 3'b010, SUB = 3'b011, AND = 3'b100 , HLT = 3'b101;

reg cnt;//指令执行需要6个阶段,用cnt计数来表示不同的阶段

always @(posedge clock or posedge reset)
        if (reset)
                // reset
                cnt <= 0;
        else
          if (cnt==5)
             cnt <= 0;
        else
          cnt <= cnt+1;
               
always@ *
    begin
            case(cnt)
               0: begin   //取指
                         s0<=1; s1<=0; s2<=0; s3<=0; s4<=0; s5<=0;
                         addrsel<=0;
               end
               1:begin      //解码
                         s0<=0; s1<=1; s2<=0; s3<=0; s4<=0; s5<=0;
                         addrsel<=0;
               end
               2:begin      //根据操作码决定是否从存储器中读取数据
                         s0<=0; s1<=0; s2<=1; s3<=0; s4<=0; s5<=0;
                         addrsel<=1;
                         if( (opcode==LDA)||
                                   (opcode==ADD)||
                                   (opcode==SUB)||
                                   (opcode==AND)   )
                            s2<=1;
                         else
                             s2<=0;
               end
               3:begin   //确定ALU的运算
                         s0<=0; s1<=0; s2<=0; s3<=1; s4<=0; s5<=0;
                         addrsel<=1;
                         if (opcode==LDA) begin
                                 instr_add<=0;
                                 instr_sub<=0;
                                 instr_and<=0;
                                 instr_pass<=1;
                         end
                         else if(opcode==ADD) begin
                                 instr_add<=1;
                                 instr_sub<=0;
                                 instr_and<=0;
                                 instr_pass<=0;
                         end
                         else if(opcode==SUB) begin
                                 instr_add<=0;
                                 instr_sub<=1;
                                 instr_and<=0;
                                 instr_pass<=0;
                         end
                         else if(opcode==AND) begin
                                 instr_add<=0;
                                 instr_sub<=0;
                                 instr_and<=1;
                                 instr_pass<=0;
                         end
                         else if(opcode==STA) begin
                                 instr_add<=0;
                                 instr_sub<=0;
                                 instr_and<=0;
                                 instr_pass<=0;
                         end
                         else begin
                                 instr_add<=0;
                                 instr_sub<=0;
                                 instr_and<=0;
                                 instr_pass<=0;
                         end
               end
               4:begin   //必要时往存储器中写数据
                      s0<=0; s1<=0; s2<=0; s3<=0; s4<=1; s5<=0;
                      addrsel<=1;
                      if(opcode==STA)
                         s4<=1;
                      else
                         s4<=0;
               end
               5:begin   //使能PC准备开始读取下一条指令
                         s0<=0; s1<=0; s2<=0; s3<=0; s4<=0; s5<=1;
                         addrsel<=1;
               end
            endcase
    end
endmodule

zhangyukun 发表于 2019-1-26 09:41:40

简易CPU的设计和实现02

zxopenljx 发表于 2019-4-23 09:34:22

简易CPU的设计和实现02
页: [1]
查看完整版本: 简易CPU的设计和实现02