集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 2406|回复: 2

简易CPU的设计和实现02

[复制链接]
fpga_feixiang 发表于 2019-1-25 13:45:18 | 显示全部楼层 |阅读模式
五.各个部件的代码实现

  1.PC部件的代码实现

module pc (clock,reset,en,pc);
input clock, reset, en;
output reg [4:0] pc;

wire [4:0] 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 [4:0] addr;  //存储器地址
input [7:0] din;   //数据线输入
output reg [7:0] dout;  //数据线输出
input wr;          //写使能端,高电平有效
input rd;          //读使能端,高电平有效

reg [7:0] mem [0:31];  //内部的存储空间

always @(posedge clock or posedge reset) begin
        if (reset) begin
            mem [0] <= 'b00001011;      //LDA 01011
            mem [1] <= 'b01001100;      //ADD 01100
            mem [2] <= 'b00101101;      //STA 01101
            mem [3] <= 'b00001011;      //LDA 01011
            mem [4] <= 'b10001100;      //AND 01100
            mem [5] <= 'b00101110;      //STA 01110
            mem [6] <= 'b00001011;      //LDA 01011
            mem [7] <= 'b01101100;      //SUB 01100
            mem [8] <= 'b00101111;      //STA 01111
            mem [9] <= 'b10100000;      //HLT
            mem [10] <= 'b00000000;
            mem [11] <= 'b10010101;
            mem [12] <= 'b01100101;
            mem [13] <= 'b00000000;
            mem [14] <= 'b00000000;
            mem [15] <= 'b00000000;
            mem [16] <= 'b00000000;
            mem [17] <= 'b00000000;
            mem [18] <= 'b00000000;
            mem [19] <= 'b00000000;
            mem [20] <= 'b00000000;
            mem [21] <= 'b00000000;
            mem [22] <= 'b00000000;
            mem [23] <= 'b00000000;
            mem [24] <= 'b00000000;
            mem [25] <= 'b00000000;
            mem [26] <= 'b00000000;
            mem [27] <= 'b00000000;
            mem [28] <= 'b00000000;
            mem [29] <= 'b00000000;
            mem [30] <= 'b00000000;
            mem [31] <= 'b00000000;
               
               
        end
        else begin
           if (wr)
              mem [addr] <= din;
           if (rd)
              dout <= mem [addr];               
        end
end
endmodule
&nbsp; 3.指令解码器(Idec)的代码实现

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

input clock,reset,en;
input [7:0] instruction;
output reg [2:0] opcode;
output reg [4:0] addr;

always @(posedge clock or posedge reset) begin
        if (reset) begin
            opcode <= 0;
            addr <= 0;
                // reset               
        end
        else if (en) begin
            opcode <= instruction [7:5];
            addr <= instruction [4:0];
               
        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 [7:0] din;
output n,z,c,v;
output reg [7:0] 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 [7:0] + din;
                        else if(sub_en)
                            {c,a} <= a [7:0] - 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 [2:0] opcode    //解码器解码后将指令码传给控制器
        );

parameter [2:0]  LDA = 3'b000, STA = 3'b001, ADD = 3'b010, SUB = 3'b011, AND = 3'b100 , HLT = 3'b101;

reg [2:0] 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 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2024-12-24 00:02 , Processed in 0.058899 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表