计算机组成原理上机实验4 有限状态机

实验目的

  • 综合利用三次实验的结果,完成以下功能:

    • 通过例化,向ram中0地址到13地址存入14个数,比如10-23;向ram中100地址到106地址存入7个数,比如0~6,分别代表运算符(与ALU的操作符对应),最后向ram 107地址写入-1

    • 运算控制:

      - 从ram 0地址开始的地方取两个数,分别放在reg0和reg1,然后从ram 100地址开始的地方取一个运算符,放到reg2,计算之后,把结果存入ram地址200
      
      - 从ram 2地址开始的地方取两个数,分别放在reg0和reg1,从ram 101地址开始的地方取一个运算符,放到reg2,计算之后,把结果存入ram地址201
      
      - ……
      
      - 如果取出操作符为-1,则结束。
      

实验平台

ISE 14.7

实验过程(分析)

  1. 模块化设计,一个alu模块,一个regfile模块,一个IP核生成的ram模块,一个control模块,控制reg、ram和alu,顶层一个top模块实例化前几个模块,ram初始化有coe文件读入。

  2. alu模块使用case语句判断7种操作类型。

  3. regfile模块用组合逻辑读,时序逻辑写。

  4. control模块思路(4周期)由于reg在这里没有实质作用(仅是复制了一份存储),故不考虑相关控制

    其中ram_ra为ram读地址,ram_rd为ram读数据,ram_we为ram写使能,tda、tdb为临时寄存上一周期的结果。

  5. 分析结果

    | Op | Data1 | Data2 | Result |
    | — | :—: | :—: | :—: |
    | 0(nop) | 11 | 10 | 0 |
    | 1(add) | 13 | 12 | 25 |
    | 2(sub) | 15 | 14 | 1 |
    | 3(and) | 17(32’b0…10001) | 16(32’b0…10000) | 16(32’b0…10000) |
    | 4(or) | 19(32’b0…10011) | 18(32’b0…10010) | 19(32’b0…10011) |
    | 5(xor) | 21(32’b0…10101) | 20(32’b0…10100) | 1(32’b0…00001) |
    | 6(nor) | 23(32’b0…10111) | 22(32’b0…10110) | -24(32’b1…101000) |

实验结果

  • 仿真结果

    IP核ram设置界面中Load In设置ram初始化coe文件的路径,其中文件内容为

      MEMORY_INITIALIZATION_RADIX=10;
    
      MEMORY_INITIALIZATION_VECTOR=
    
      10,11,12,13,14,15,16,17,18,19,20,21,22,23,0,0,
    
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
      0,0,0,0,0,1,2,3,4,5,6,-1,0,0,0,0,
    
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    

    仿真得ram和reg数据为

    ……

    ……

    可见计算结果符合分析。

附录:

  • 模块源代码

    top.v

    module top(
        input clk,
        input rst_n
    );
    
        wire [5:0] ra;
        wire [5:0] wa;
        wire [31:0] rd;
        wire [31:0] wd;
        wire [31:0] aluout;
    
        reg we=1'b1;
        wire [31:0] tda;
        wire [31:0] tdb;    
    
        wire clkb;
        wire ram_we;
        wire [7:0] ram_ra;
        wire [7:0] ram_wa;
        wire [31:0] ram_rd;
        wire [31:0] ram_wd;
    
        alu alu1(ram_rd,tdb,tda,aluout);
        regfile regfile1(clk,rst_n,ra,wa,wd,we,rd);
        control control1(clk,rst_n,aluout,ra,rd,wa,wd,tda,tdb,ram_we,ram_ra,ram_rd,ram_wa,ram_wd);
        ram ram1(clk,ram_we,ram_wa,ram_wd,clk,ram_ra,ram_rd);
    
    endmodule
    

    alu.v

    parameter A_NOP =5'h00; //nop
    parameter A_ADD =5'h01; //sign_add
    parameter A_SUB =5'h02; //sign_sub
    parameter A_AND =5'h03; //and
    parameter A_OR  =5'h04; //or
    parameter A_XOR =5'h05; //xor
    parameter A_NOR =5'h06; //nor
    
    module alu(
        input [31:0] alu_a,
        input [31:0] alu_b,
        input [4:0] alu_op,
        output reg [31:0] alu_out
        );
        always@(*)
            case (alu_op)
                A_NOP: alu_out = 0;
                A_ADD: alu_out = alu_a + alu_b;
                A_SUB: alu_out = alu_a - alu_b;
                A_AND: alu_out = alu_a & alu_b;
                A_OR : alu_out = alu_a | alu_b;
                A_XOR: alu_out = alu_a ^ alu_b;
                A_NOR: alu_out = ~(alu_a | alu_b);
                default: alu_out = 0;
            endcase
    endmodule
    

    regfile.v

    module regfile(
        input   clk,
        input rst_n,
        input [5:0] rAddr1,//读地址
        input [5:0] wAddr,//写地址
        input [31:0] wDin,//写数据
        input wEna,//写使能
        output [31:0] rDout1//读数据1
    );
        reg [31:0] data [0:63];
        integer i;
        assign rDout1=data[rAddr1];//读
    
        always@(posedge clk or rst_n)//写和复位
            if(~rst_n)
            begin 
                for(i=0; i<64; i=i+1) data[i]<=0;
            end
            else
            begin
                if(wEna)
                    data[wAddr]<=wDin;
            end
    endmodule
    

    control.v

    module control(
        input clk,rst_n,
        input [31:0] aluout,
    
        output reg [5:0] ra=6'd0,//reg read addr
        input [31:0] rd,//reg read data
        output reg [5:0] wa=6'd0,//reg write addr
        output reg [31:0] wd,//reg write data
    
        output reg [31:0] tda,//tmp data a
        output reg [31:0] tdb,//tmp data b
    
        output reg ram_we,//ram write enable
        output reg [7:0] ram_ra,//ram read addr
        input [31:0] ram_rd,//ram read data
        output reg [7:0] ram_wa,//ram write addr
        output reg [31:0] ram_wd//ram write data
        );
        reg [2:0] cstate;//current state
        reg [2:0] nstate;//next state
        reg endflag=0;
        integer i=0;
    
        always @(posedge clk or negedge rst_n)
            if(~rst_n) 
                cstate<=3'd0;
            else 
                cstate<=nstate;
    
        always @(*)
            if(cstate==3'd0) nstate=3'd1;
            else if(cstate==3'd1 & endflag==1'd0) nstate=3'd2;
            else if(cstate==3'd1 & endflag==1'd1) nstate=3'd5;
            else if(cstate==3'd2) nstate=3'd3;
            else if(cstate==3'd3) nstate=3'd4;
            else if(cstate==3'd4) nstate=3'd1;
            else if(cstate==3'd5) nstate=3'd5;
        always @(negedge clk or negedge rst_n)
        begin
            if(~rst_n)
                begin
                    ram_ra<=0;
                    ram_wa<=0;
                    i<=0;
                end
            else if(cstate==3'd1)
                begin
                    ram_ra<=100+i;  
                end
            else if(cstate==3'd2)
                begin
                    ram_ra<=2*i;
                    tda<=ram_rd;
                    if(ram_rd==-1) endflag<=1;
                end
            else if(cstate==3'd3)
                begin
                    ram_ra<=2*i+1;
                    tdb<=ram_rd;
                end
            else if(cstate==3'd4)
                begin
                    ram_wa<=200+i;
                    ram_we<=1;
                    ram_wd<=aluout;
                    i<=i+1;
                end         
        end
    
    endmodule
    

    test.v

    module test(
        );
        reg clk,rst_n;
        top test(
            .clk(clk),
            .rst_n(rst_n),
        );
        always #10 clk=~clk;
        initial begin
            clk=0;
            rst_n=0;
            #20;
            rst_n=1;
        end
    endmodule
    
文章目录
  1. 实验目的
  2. 实验平台
  3. 实验过程(分析)
  4. 实验结果
  5. 附录:
|