实验报告
2021   年    7   月     1   日                           成绩:
 专业         计算机科学与技术              课程名称          计算机组成原理实验
实验名称                             中断系统及系统调试实验
                                  19201218   李之昊
组内成员
                                  19201127   汤贤林
学号姓名
                                  19063110   蔡思林
                           组长学
任课老师        章复嘉                              19201218 李之昊
                       号、姓名
                                  中断移植虚
实验时间        2021/7/1   实验地点       仿真实验平 实验设备号
                                     台
一、实验目的与要求
1、实验目的:
 a) 理解主程序和两个 irq 中断服务程序的功能;
 b) 任选一个 irq 中断服务程序,以主程序和该 irq 中断服务程序为测试程序,
      联调前置实验实现的部件,调试实验所实现的中断返回指令和中断隐指
      构建完整的 irq 中断全过程。
2、实验要求:
 (1)在实验步骤 10 实现的工程基础上修改和扩充;
 (2)运行测试程序,观察每条指令的执行结果;
 (3)根据指令执行结果,判断实验步骤 6~8 所实现的中断控制部件双堆栈指
 针结构、寄存器堆部件的功能的正确性;
 (4)根据指令执行结果,判断实验步骤 9、10 所实现的中断返回指和中断隐指
 令的正确性;
 (5)分析是否正确构建了完整的 irq 中断全过程
二、实验设计与程序代码
1、模块设计说明
外层 CPU 模块,连接各个模块,控制和译码单元也在该模块中
INST 模块,负责取指令相关数据通路设计以及 PC 程序计数器和指令存储器
Register_pile 模块,九种工作模式的通用寄存器堆
ALU_Shift 模块连接桶形移位器和 ALU 模块
Data_RAM 数据寄存器
Reg_CPSR,程序状态寄存器模块
Request 模块,中断控制电路
Stack 模块,双堆栈指针以及堆栈相关电路
程序中还使用了多种 D 触发器模块就不在此处说明了
2、实验程序源代码及注释等
  (实验各个模块的代码,包含功能注释)
//CPSR
   Reg_CPSR CPSR_Instance(
   .clk(clk),
   .rst(Rst),
   .W_SPSR_s(W_SPSR_s),
   .W_CPSR_s(W_CPSR_s),
   .Write_SPSR(Write_SPSR),
   .Write_CPSR(Write_CPSR),
   .SPSR_New(SPSR_New),
   .CPSR_New(CPSR_New),
   .MASK(MASK),
   .NZCV(NZCV),
.Change_M(Change_M),
.S(S),
.CPSR(CPSR),
.Curr_SPSR(SPSR)
);
reg INTA_irq,INTA_fiq;
//中断请求处理
request request_Instance(
.CPSR_6(CPSR[6]),
.CPSR_7(CPSR[7]),
.INTA_irq(INTA_irq),
.INTA_fiq(INTA_fiq),
.EX_irq(EX_irq),
.EX_fiq(EX_fiq),
.Rst(Rst),
.INT_irq(INT_irq),
.INT_fiq(INT_fiq)
);
assign INTA = INTA_fiq | INTA_irq;
always@(posedge INTA or posedge Rst)
begin
    if (Rst)
        INT_Data <= 0;
    else
        INT_Data <= INT_Vector;
end
//双堆栈指针
wire [31:0] SP,MSP,PSP;
Stack Stack_Instance(
.clk(clk),
.rst(Rst),
.SP_in(SP_in),
.SP_out(SP_out),
.M(CPSR[4:0]),
.SP(SP),
.PSP(PSP),
.MSP(MSP)
);
localparam Idle = 6'd0;
localparam S0   = 6'd1;
localparam S1   = 6'd2;
localparam S2   = 6'd3;
localparam S3   = 6'd4;
localparam S7   = 6'd8;
localparam S8   = 6'd9;
localparam S9   = 6'd10;
localparam S10 = 6'd11;
localparam S11 = 6'd12;
localparam S12 = 6'd13;
localparam S13 = 6'd14;
localparam S14 = 6'd15;
localparam S15 = 6'd16;
localparam S16 = 6'd17;
localparam S17 = 6'd18;
localparam S18 = 6'd19;
localparam S19 = 6'd20;
localparam S20 = 6'd21;
localparam S21 = 6'd22;
localparam S22 = 6'd23;
localparam S23 = 6'd24;
localparam S24 = 6'd25;
localparam S25 = 6'd26;
localparam S26 = 6'd27;
localparam S27 = 6'd28;
localparam S28 = 6'd29;
localparam S29 = 6'd30;
localparam S30 = 6'd31;
localparam S31 = 6'd32;
reg [5:0] ST,Next_ST;
always@(*)//次态函数
begin
    Next_ST = Idle;
    case(ST)
        Idle:    Next_ST = S0;
        S0:
        begin
            if (flag & !Und_Ins)
                case(DP)
                    B1:Next_ST      = S8;
                    BL:Next_ST      = S10;
                    default:Next_ST = S1;
                  endcase
              else
                  Next_ST = S0;
          end
          S1:
          begin
              if (DP == BX)
                  Next_ST = S7;
              else if (DP == MOVS)
                  Next_ST = S28;
              else if (DP[3])
                  Next_ST = S12;
              else if (DP == SWP)
                  Next_ST = S16;
              else
                  Next_ST = S2;
          end
          S26:     Next_ST = S27;
          S28:     Next_ST = S26;
          S29:     Next_ST = S30;
          S30:     Next_ST = S31;
          S31:     Next_ST = S27;
          default: begin
              if ((INT_irq & !CPSR[7])|(INT_fiq & !CPSR[6]))
                  Next_ST = S29;
              else
                  Next_ST = S0;
          end
      endcase
end
always@(posedge clk or posedge Rst)//输出函数
begin
    if (Rst)
    begin
        Write_PC   <= 1'b0;
        Write_IR   <= 1'b0;
        Write_Reg <= 1'b0;
        LA         <= 1'b0;
        LB         <= 1'b0;
        LC         <= 1'b0;
        LF         <= 1'b0;
        S          <= 1'b0;
   rm_imm_s     <=   1'b0;
   rs_imm_s     <=   2'b00;
   PC_s         <=   2'b00;
   rd_s         <=   2'b00;
   ALU_A_s      <=   1'b0;
   ALU_B_s      <=   2'b00;
   W_Rdata_s    <=   1'b0;
   Reg_C_s      <=   1'b0;
   Mem_Write    <=   1'b0;
   Mem_W_s      <=   1'b0;
   Write_CPSR   <=   1'b0;
   Write_SPSR   <=   1'b0;
   ALU_OP       <=   4'b0000;
   W_CPSR_s     <=   3'b000;
   W_SPSR_s     <=   1'b0;
   SP_out       <=   1'b0;
   SP_in        <=   1'b0;
   Change_M     <=   3'b000;
   INTA_irq     <=   1'b0;
   INTA_fiq     <=   1'b0;
end
else
begin
    case(Next_ST)
        S0:begin
            Write_PC     <=     1'b1;
            Write_IR     <=     1'b1;
            Write_Reg    <=     1'b0;
            LA           <=     1'b0;
            LB           <=     1'b0;
            LC           <=     1'b0;
            LF           <=     1'b0;
            S            <=     1'b0;
            rm_imm_s     <=     1'b0;
            rs_imm_s     <=     2'b00;
            PC_s         <=     2'b00;
            rd_s         <=     2'b00;
            ALU_A_s      <=     1'b0;
            ALU_B_s      <=     2'b00;
            W_Rdata_s    <=     1'b0;
            Reg_C_s      <=     1'b0;
            Mem_Write    <=     1'b0;
            Mem_W_s      <=     1'b0;
            Write_CPSR   <=     1'b0;
   Write_SPSR    <=   1'b0;
   ALU_OP        <=   4'b0000;
   W_CPSR_s      <=   3'b000;
   W_SPSR_s      <=   1'b0;
   SP_out        <=   1'b0;
   SP_in         <=   1'b0;
   Change_M      <=   3'b000;
   INTA_irq      <=   1'b0;
   INTA_fiq      <=   1'b0;
end
S1:begin
    Write_PC     <=   1'b0;
    Write_IR     <=   1'b0;
    LA           <=   1'b1;
    LB           <=   1'b1;
    LC           <=   1'b1;
end
S26:begin
    Write_PC      <=   1'b1;
    LF            <=   1'b0;
    S             <=   1'b0;
    PC_s          <=   2'b10;
    Write_CPSR    <=   1'b1;
    W_CPSR_s      <=   3'b000;
    SP_out        <=   1'b1;
end
S27:begin
    Write_PC      <=   1'b0;
    PC_s          <=   2'b00;
    Write_CPSR    <=   1'b0;
    W_CPSR_s      <=   3'b000;
    SP_out        <=   1'b0;
    SP_in         <=   1'b1;
    INTA_irq      <=   1'b0;
    INTA_fiq      <=   1'b0;
end
S28:begin
    LA            <=   1'b0;
    LB            <=   1'b0;
    LC            <=   1'b0;
    LF            <=   1'b1;
    S             <=   IR[20];
    ALU_OP        <=   4'b1101;
end
    S29:begin
        Write_PC     <=   1'b0;
        Write_IR     <=   1'b0;
        Write_Reg    <=   1'b0;
        LA           <=   1'b0;
        LB           <=   1'b0;
        LC           <=   1'b0;
        LF           <=   1'b1;
        S            <=   1'b0;
        rm_imm_s     <=   1'b0;
        rs_imm_s     <=   2'b00;
        PC_s         <=   2'b00;
        rd_s         <=   2'b00;
        ALU_A_s      <=   1'b1;
        ALU_B_s      <=   2'b00;
        W_Rdata_s    <=   1'b0;
        Reg_C_s      <=   1'b0;
        Mem_Write    <=   1'b0;
        Mem_W_s      <=   1'b0;
        Write_CPSR   <=   1'b0;
        Write_SPSR   <=   1'b0;
        ALU_OP       <=   4'b1000;
        W_CPSR_s     <=   3'b000;
        W_SPSR_s     <=   1'b0;
        SP_out       <=   1'b0;
        SP_in        <=   1'b0;
        INTA_irq     <=   1'b0;
        INTA_fiq     <=   1'b0;
    end
    S30:begin
        Write_Reg         <=   1'b1;
        LF                <=   1'b0;
        rd_s              <=   2'b01;
        ALU_A_s           <=   1'b0;
        Write_SPSR        <=   1'b1;
        ALU_OP            <=   4'b0000;
        W_SPSR_s          <=   1'b1;
        Change_M          <=   (INT_fiq & !CPSR[6])?3'b001:3'b010
;
    end
    S31:begin
        Write_PC     <= 1'b1;
        Write_Reg    <= 1'b0;
        PC_s         <= 2'b11;
                       rd_s         <=   2'b00;
                       Write_CPSR   <=   1'b1;
                       Write_SPSR   <=   1'b0;
                       W_CPSR_s     <=   (INT_fiq & !CPSR[6])?3'b011:3'b010;
                       W_SPSR_s     <=   1'b0;
                       SP_out       <=   1'b1;
                       Change_M     <=   3'b000;
                       INTA_irq     <=   (INT_fiq & !CPSR[6])?1'b0:1'b1;
                       INTA_fiq     <=   (INT_fiq & !CPSR[6])?1'b1:1'b0;
                 end
             endcase
       end
    end
module Reg_CPSR(input clk,
                input rst,
                input W_SPSR_s,
                input [2:0] W_CPSR_s,
                input Write_SPSR,
                input Write_CPSR,
                input [31:0] SPSR_New,
                input [31:0] CPSR_New,
                input [3:0] MASK,
                input [3:0] NZCV,
                input [2:0] Change_M,
                input S,
                output [31:0] SPSR_fiq,
                output [31:0] SPSR_irq,
                output [31:0] SPSR_abt,
                output [31:0] SPSR_svc,
                output [31:0] SPSR_und,
                output [31:0] SPSR_mon,
                output [31:0] SPSR_hyp,
                output [31:0] CPSR,
                output reg [31:0] Curr_SPSR
                );
    reg [31:0] CPSR_in;
    wire [31:0] new_SPSR;
    reg [6:0] clk_m;
    reg [4:0] M;
   assign new_SPSR      = (W_SPSR_s == 1)? CPSR : SPSR_New;
   //    assign CPSR_in = (W_CPSR_s == 1)? CPSR_New : Curr_SPSR;
always@(Change_M or CPSR[4:0]) begin
    case(Change_M)
        3'd0: M <= CPSR[4:0];
        3'd1: M <= 5'b10001; //fiq
        3'd2: M <= 5'b10010; //irq
        3'd3: M <= 5'b10011; //svc
        3'd4: M <= 5'b11011; //und
    endcase
end
always@(*)begin
    case(W_CPSR_s)
        3'd0: CPSR_in   <=   Curr_SPSR;
        3'd1: CPSR_in   <=   CPSR_New;
        3'd2: CPSR_in   <=   {CPSR[31:8],8'h92};   //irq
        3'd3: CPSR_in   <=   {CPSR[31:8],8'hD1};   //fiq
        3'd4: CPSR_in   <=   {CPSR[31:8],8'h93};   //svc
        3'd5: CPSR_in   <=   {CPSR[31:8],8'h1B};   //und
    endcase
end
always@(M[4:0]) begin
    if (M[4]) begin
        case(M[3:0])
            4'b0001: begin
                clk_m = 7'b0000001;
                Curr_SPSR <= SPSR_fiq;
            end
            4'b0010: begin
                clk_m = 7'b0000010;
                Curr_SPSR <= SPSR_irq;
            end
            4'b0011: begin
                clk_m = 7'b0000100;
                Curr_SPSR <= SPSR_svc;
            end
            4'b0110: begin
                clk_m = 7'b0001000;
                Curr_SPSR <= SPSR_mon;
            end
            4'b0111: begin
                clk_m = 7'b0010000;
                Curr_SPSR <= SPSR_abt;
            end
                4'b1010: begin
                    clk_m = 7'b0100000;
                    Curr_SPSR <= SPSR_hyp;
                end
                4'b1011: begin
                    clk_m = 7'b1000000;
                    Curr_SPSR <= SPSR_und;
                end
            endcase
      end
end
//SPSR
d_flip_flop_32 D_SPSR_fiq(
.d(new_SPSR),
.clk(~clk & Write_SPSR & clk_m[0]),
.q(SPSR_fiq),
.clr(rst)
);
d_flip_flop_32 D_SPSR_irq(
.d(new_SPSR),
.clk(~clk & Write_SPSR & clk_m[1]),
.q(SPSR_irq),
.clr(rst)
);
d_flip_flop_32 D_SPSR_svc(
.d(new_SPSR),
.clk(~clk & Write_SPSR & clk_m[2]),
.q(SPSR_svc),
.clr(rst)
);
d_flip_flop_32 D_SPSR_mon(
.d(new_SPSR),
.clk(~clk & Write_SPSR & clk_m[3]),
.q(SPSR_mon),
.clr(rst)
);
d_flip_flop_32 D_SPSR_abt(
.d(new_SPSR),
.clk(~clk & Write_SPSR & clk_m[4]),
.q(SPSR_abt),
.clr(rst)
);
   d_flip_flop_32 D_SPSR_hyp(
   .d(new_SPSR),
   .clk(~clk & Write_SPSR & clk_m[5]),
   .q(SPSR_hyp),
   .clr(rst)
   );
   d_flip_flop_32 D_SPSR_und(
   .d(new_SPSR),
   .clk(~clk & Write_SPSR & clk_m[6]),
   .q(SPSR_und),
   .clr(rst)
   );
    //CPSR
    d_flip_flop_8_2 D_CPSR_7_0(
    .d(CPSR_in[7:0]),
    .clk(~clk & Write_CPSR & ~(W_CPSR_s[0] & ~MASK[0] & ~W_CPSR_s[1] &
~W_CPSR_s[2])),
    .q(CPSR[7:0]),
    .clr(rst)
    );
    d_flip_flop_8 D_CPSR_15_8(
    .d(CPSR_in[15:8]),
    .clk(~clk & Write_CPSR & ((~W_CPSR_s[0] & ~W_CPSR_s[1] & ~W_CPSR_s[
2]) | (~W_CPSR_s[1] & ~W_CPSR_s[2] & MASK[1]))),
    .q(CPSR[15:8]),
    .clr(rst)
    );
    d_flip_flop_8 D_CPSR_23_16(
    .d(CPSR_in[23:16]),
    .clk(~clk & Write_CPSR & ((~W_CPSR_s[0] & ~W_CPSR_s[1] & ~W_CPSR_s[
2]) | (~W_CPSR_s[1] & ~W_CPSR_s[2] & MASK[2]))),
    .q(CPSR[23:16]),
    .clr(rst)
    );
    d_flip_flop_4 D_CPSR_27_24(
    .d(CPSR_in[27:24]),
    .clk(~clk & Write_CPSR & ((~W_CPSR_s[0] & ~W_CPSR_s[1] & ~W_CPSR_s[
2]) | (~W_CPSR_s[1] & ~W_CPSR_s[2] & MASK[3]))),
    .q(CPSR[27:24]),
    .clr(rst)
    );
    d_flip_flop_4 D_CPSR_31_28(
    .d((S == 0)? CPSR_in[31:28] : NZCV),
    .clk((~clk & Write_CPSR & ((~W_CPSR_s[0] & ~W_CPSR_s[1] & ~W_CPSR_s
[2]) | (~W_CPSR_s[1] & ~W_CPSR_s[2] & MASK[3]))) | (~clk & S)),
    .q(CPSR[31:28]),
    .clr(rst)
    );
endmodule
   module d_flip_flop_32(
       input [31:0]d,
       input clk,
       input clr,
       output reg [31:0] q
       );
       always@ (posedge clk or posedge clr) begin
           if (clr) begin
               q <= 0;
           end
           else begin
               q <= d;
           end
       end
   endmodule
       module d_flip_flop_4(
           input [3:0]d,
           input clk,
           input clr,
           output reg [3:0] q
           );
           always@ (posedge clk or posedge clr) begin
               if (clr) begin
                   q <= 0;
               end
               else begin
                   q <= d;
               end
           end
       endmodule
           module d_flip_flop_8(
               input [7:0]d,
               input clk,
               input clr,
               output reg [7:0] q
               );
               always@ (posedge clk or posedge clr) begin
                   if (clr) begin
                       q <= 0;
                   end
                   else begin
                       q <= d;
                   end
               end
           endmodule
               module d_flip_flop_8_2(
                   input [7:0]d,
                   input clk,
                   input clr,
                   output reg [7:0] q
                   );
                   always@ (posedge clk or posedge clr) begin
                       if (clr) begin
                           q <= 8'h10;
                       end
                       else begin
                           q <= d;
                       end
                   end
               endmodule
module d_flip_flop(input d,
                   input clk,
                   input clr,
                   output reg q);
   always@ (posedge clk or posedge clr)
   begin
       if (clr)
       begin
            q <= 0;
         end
         else
         begin
             q <= d;
         end
   end
endmodule
module request(
    input CPSR_6,
    input CPSR_7,
    input INTA_irq,
    input INTA_fiq,
    input EX_irq,
    input EX_fiq,
    input Rst,
   output INT_irq,
   output INT_fiq);
   d_flip_flop D1(
   .d(1'b1),
   .clk(~CPSR_6),
   .clr(INTA_fiq),
   .q(Q_fiq)
   );
   d_flip_flop D2(
   .d(Q_fiq),
   .clk(EX_fiq),
   .clr(INTA_fiq|Rst),
   .q(INT_fiq)
   );
   d_flip_flop D3(
   .d(1'b1),
   .clk(~CPSR_7),
   .clr(INTA_irq),
   .q(Q_irq)
   );
   d_flip_flop D4(
   .d(Q_irq),
   .clk(EX_irq),
   .clr(INTA_irq|Rst),
   .q(INT_irq_tmp)
   );
   assign INT_irq = ~INT_fiq & INT_irq_tmp;
endmodule
module Stack(input clk,
             input rst,
             input SP_in,
             input SP_out,
             input [4:0] M,
             output reg [31:0] SP,
             output reg [31:0] PSP,
             output reg [31:0] MSP);
   reg [31:0] SP,SP_fiq,SP_irq,SP_svc,SP_mon,SP_abt,SP_hyp,SP_und;
   always @(posedge clk or posedge rst) begin
       if (rst) begin
           MSP <= 32'h0000_0020;
           PSP <= 0;
       end
       else begin
           if (SP_out && M[4]) begin
               case(M[3:0])
                   4'd0: PSP <= SP;
                   4'd1: MSP <= SP_fiq;
                   4'd2: MSP <= SP_irq;
                   4'd3: MSP <= SP_svc;
                   4'd6: MSP <= SP_mon;
                   4'd7: MSP <= SP_abt;
                   4'd10: MSP <= SP_hyp;
                   4'd11: MSP <= SP_und;
                   4'd15: MSP <= SP;
                   default:;
               endcase
           end
               if (SP_in && M[4]) begin
                   case(M[3:0])
                       4'd0: SP      <= PSP;
                       4'd1: SP_fiq <= MSP;
                         4'd2: SP_irq    <=   MSP;
                         4'd3: SP_svc    <=   MSP;
                         4'd6: SP_mon    <=   MSP;
                         4'd7: SP_abt    <=   MSP;
                         4'd10: SP_hyp   <=   MSP;
                         4'd11: SP_und   <=   MSP;
                         4'd15: SP       <=   MSP;
                     endcase
               end
       end
    end
endmodule
三、实验仿真
1、仿真代码
`timescale 1ns / 1ps
module testcpu();
    reg clk, Rst, EX_irq,EX_fiq;
    reg [31:0] INT_Vector;
    wire [31:0] I;
    wire [31:0] A,B,C,F;
    wire Write_PC,Write_IR,Write_Reg,S,Write_CPSR,Write_SPSR,SP_in,SP_o
ut;
    wire rm_imm_s;
    wire [1:0] rs_imm_s,PC_s;
    wire [3:0] ALU_OP;
    wire ALU_A_s,W_Rdata_s,Reg_C_s,W_SPSR_s;
    wire [1:0] rd_s,ALU_B_s;
    wire [2:0] Change_M,W_CPSR_s;
    wire [31:0] CPSR,SPSR;
    wire [7:2] Inst_addr;
    wire [3:0] DP;
    wire INT_irq,INT_fiq;
    CPU cpu(
    .clk(clk),
    .Rst(Rst),
    .EX_irq(EX_irq),
    .EX_fiq(EX_fiq),
    .INT_Vector(INT_Vector),
    .I(I),
.A(A),
.B(B),
.C(C),
.F(F),
.CPSR(CPSR),
.SPSR(SPSR),
.Write_PC(Write_PC),
.Write_IR(Write_IR),
.Write_Reg(Write_Reg),
.Write_CPSR(Write_CPSR),
.Write_SPSR(Write_SPSR),
.SP_in(SP_in),
.SP_out(SP_out),
.rm_imm_s(rm_imm_s),
.rs_imm_s(rs_imm_s),
.ALU_OP(ALU_OP),
.S(S),
.PC_s(PC_s),
.rd_s(rd_s),
.ALU_A_s(ALU_A_s),
.ALU_B_s(ALU_B_s),
.Inst_addr(Inst_addr),
.W_Rdata_s(W_Rdata_s),
.W_CPSR_s(W_CPSR_s),
.W_SPSR_s(W_SPSR_s),
.Reg_C_s(Reg_C_s),
.INT_irq(INT_irq),
.INT_fiq(INT_fiq),
.DP(DP),
.Change_M(Change_M));
initial
begin
    INT_Vector = 8'h00000020;
    clk    = 0;
    EX_irq = 0;
    EX_fiq = 0;
    #5
    Rst = 1;
    #45
    Rst = 0;
   #400
   EX_irq = 1;
   #50
      EX_irq = 0;
      #500
      INT_Vector = 8'h00000020;
      EX_irq = 1;
      #50
      EX_irq = 0;
      #300
      INT_Vector = 8'h00000020;
      EX_irq = 1;
      #50
      EX_irq = 0;
      #800
      INT_Vector = 8'h00000020;
      EX_irq = 1;
      #50
      EX_irq = 0;
      #1000
      INT_Vector = 8'h00000020;
      EX_irq = 1;
      #50
      EX_irq = 0;
      #400
      INT_Vector = 8'h00000020;
      EX_irq = 1;
      #50
      EX_irq = 0;
      #700
      INT_Vector = 8'h00000020;
      EX_irq = 1;
      #50
      EX_irq = 0;
end
initial
   begin
       #800
       INT_Vector = 8'h00000040;
       EX_fiq = 1;
       #50
       EX_fiq = 0;
         #900
         INT_Vector = 8'h00000040;
         EX_fiq = 1;
         #50
         EX_fiq = 0;
   end
    initial
        forever #20 clk = ~clk;
endmodule
2、仿真波形
3、仿真结果分析
上面两张图可以看到,第一次发出 EX_irq 后,产生 INT_irq 信号,直到当前指令结束,进
入 S31 状态后,才变为 0,并进入 irq 中断测试程序,此时发出了 EX_fiq 信号,产生了 INT_fiq
信号,在当前指令执行完后,发生了中断抢占,进入了 fiq 中断程序,此时又发出了一个
EX_irq 信号,但由于此时 irq 和 fiq 中断都被禁止,因此没有产生 INT_irq 信号,也不会发
生中断。
上面两图可见,两次中断都成功返回
四、电路图
五、引脚配置
# 开启比特流压缩,优化 .bit 文件大小
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
# Switch,开关
set_property PULLDOWN true [get_ports sw]
set_property IOSTANDARD LVCMOS18 [get_ports sw]
set_property PACKAGE_PIN T3 [get_ports {sw[1]}]
set_property PACKAGE_PIN U3    [get_ports {sw[2]}]
set_property PACKAGE_PIN T4 [get_ports {sw[3]}]
set_property PACKAGE_PIN V3 [get_ports {sw[4]}]
set_property PACKAGE_PIN V4 [get_ports {sw[5]}]
set_property PACKAGE_PIN W4 [get_ports {sw[6]}]
set_property PACKAGE_PIN Y4 [get_ports {sw[7]}]
set_property PACKAGE_PIN Y6 [get_ports {sw[8]}]
set_property PACKAGE_PIN W7 [get_ports {sw[9]}]
set_property PACKAGE_PIN Y8 [get_ports {sw[10]}]
set_property PACKAGE_PIN Y7 [get_ports {sw[11]}]
set_property PACKAGE_PIN T1 [get_ports {sw[12]}]
set_property PACKAGE_PIN U1    [get_ports {sw[13]}]
set_property PACKAGE_PIN U2    [get_ports {sw[14]}]
set_property PACKAGE_PIN W1 [get_ports {sw[15]}]
set_property PACKAGE_PIN W2 [get_ports {sw[16]}]
set_property PACKAGE_PIN Y1 [get_ports {sw[17]}]
set_property PACKAGE_PIN AA1 [get_ports {sw[18]}]
set_property PACKAGE_PIN V2 [get_ports {sw[19]}]
set_property PACKAGE_PIN Y2 [get_ports {sw[20]}]
set_property PACKAGE_PIN AB1 [get_ports {sw[21]}]
set_property PACKAGE_PIN AB2 [get_ports {sw[22]}]
set_property PACKAGE_PIN AB3 [get_ports {sw[23]}]
set_property PACKAGE_PIN AB5 [get_ports {sw[24]}]
set_property PACKAGE_PIN AA6 [get_ports {sw[25]}]
set_property PACKAGE_PIN R2 [get_ports {sw[26]}]
set_property PACKAGE_PIN R3 [get_ports {sw[27]}]
set_property PACKAGE_PIN T6 [get_ports {sw[28]}]
set_property PACKAGE_PIN R6 [get_ports {sw[29]}]
set_property PACKAGE_PIN U7    [get_ports {sw[30]}]
set_property PACKAGE_PIN AB7 [get_ports {sw[31]}]
set_property PACKAGE_PIN AB8 [get_ports {sw[32]}]
# Switch Button,按钮
set_property IOSTANDARD LVCMOS18 [get_ports swb]
set_property PACKAGE_PIN R4 [get_ports {swb[1]}]
set_property PACKAGE_PIN AA4 [get_ports {swb[2]}]
set_property PACKAGE_PIN AB6 [get_ports {swb[3]}]
set_property PACKAGE_PIN T5 [get_ports {swb[4]}]
set_property PACKAGE_PIN V8 [get_ports {swb[5]}]
set_property PACKAGE_PIN AA8 [get_ports {swb[6]}]
# LED
set_property PULLDOWN true [get_ports led]
set_property IOSTANDARD LVCMOS18 [get_ports led]
set_property PACKAGE_PIN R1 [get_ports {led[1]}]
set_property PACKAGE_PIN P2 [get_ports {led[2]}]
set_property PACKAGE_PIN P1 [get_ports {led[3]}]
set_property PACKAGE_PIN N2 [get_ports {led[4]}]
set_property PACKAGE_PIN M1 [get_ports {led[5]}]
set_property PACKAGE_PIN M2 [get_ports {led[6]}]
set_property PACKAGE_PIN L1 [get_ports {led[7]}]
set_property PACKAGE_PIN J2 [get_ports {led[8]}]
set_property PACKAGE_PIN G1 [get_ports {led[9]}]
set_property PACKAGE_PIN E1 [get_ports {led[10]}]
set_property PACKAGE_PIN D2 [get_ports {led[11]}]
set_property PACKAGE_PIN A1 [get_ports {led[12]}]
set_property PACKAGE_PIN L3 [get_ports {led[13]}]
set_property PACKAGE_PIN G3 [get_ports {led[14]}]
set_property PACKAGE_PIN K4 [get_ports {led[15]}]
set_property PACKAGE_PIN G4 [get_ports {led[16]}]
set_property PACKAGE_PIN K1 [get_ports {led[17]}]
set_property PACKAGE_PIN J1 [get_ports {led[18]}]
set_property PACKAGE_PIN H2 [get_ports {led[19]}]
set_property PACKAGE_PIN G2 [get_ports {led[20]}]
set_property PACKAGE_PIN F1 [get_ports {led[21]}]
set_property PACKAGE_PIN E2 [get_ports {led[22]}]
set_property PACKAGE_PIN D1 [get_ports {led[23]}]
set_property PACKAGE_PIN B1 [get_ports {led[24]}]
set_property PACKAGE_PIN B2 [get_ports {led[25]}]
set_property PACKAGE_PIN N3 [get_ports {led[26]}]
set_property PACKAGE_PIN M3 [get_ports {led[27]}]
set_property PACKAGE_PIN K3 [get_ports {led[28]}]
set_property PACKAGE_PIN H3 [get_ports {led[29]}]
set_property PACKAGE_PIN N4 [get_ports {led[30]}]
set_property PACKAGE_PIN L4 [get_ports {led[31]}]
set_property PACKAGE_PIN J4 [get_ports {led[32]}]
# 数码管相关
set_property IOSTANDARD LVCMOS18 [get_ports seg]
set_property PACKAGE_PIN H19 [get_ports {seg[7]}]
set_property PACKAGE_PIN G20 [get_ports {seg[6]}]
set_property PACKAGE_PIN J22 [get_ports {seg[5]}]
set_property PACKAGE_PIN K22 [get_ports {seg[4]}]
set_property PACKAGE_PIN K21 [get_ports {seg[3]}]
set_property PACKAGE_PIN H20 [get_ports {seg[2]}]
set_property PACKAGE_PIN H22 [get_ports {seg[1]}]
set_property PACKAGE_PIN J21 [get_ports {seg[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports which]
set_property PACKAGE_PIN N22 [get_ports {which[0]}]
set_property PACKAGE_PIN M21 [get_ports {which[1]}]
set_property PACKAGE_PIN M22 [get_ports {which[2]}]
set_property -dict {IOSTANDARD LVCMOS18 PACKAGE_PIN L21} [get_ports
enable]
set_property -dict {IOSTANDARD LVCMOS18 PACKAGE_PIN H4} [get_ports clk]
# [Place 30-574] Poor placement for routing between an IO pin and BUFG.If this
# sub optimal condition is acceptable for this design, you may use the
# CLOCK_DEDICATED_ROUTE constraint in the .xdc file to demote this message to
a
# WARNING. However, the use of this override is highly discouraged.
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_IBUF]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets swb_IBUF[1]]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets swb_IBUF[2]]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets swb_IBUF[3]]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets swb_IBUF[4]]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets swb_IBUF[5]]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets swb_IBUF[6]]
六、组内分工
李之昊:设计中断模块,编写中断模块的代码,并进行验证
汤贤林:编写顶层模块,通过板级实验,验证正确性
蔡思林:编写仿真测试模块,通过仿真测试模块正确性
七、实验总结及思考探索
1、实验结果记录:
由于时间有限,未能将实验结果记录成表,实验结果可见仿真波形图
2、实验结论:
结果分析见仿真结果分析
通过本次实验,我们更加深入的了解了 Arm 中断的机制,实现了 irq 中断和 fiq
中断,并熟悉了其作用和产生机制,同时完整的实现了一个多周期多指令可中断
的简易 CPU
3、问题与解决方案:
做 1013 时我去找 D 触发器相关的代码,一开始找的代码没有复位的功能所以错了,后面修
改了就没问题了。
做 1014 时,我一开始把对应信号在每个状态里都设置然后写成了代码,过程里根据判题错
误猜测是哪里出错,慢慢从 0 到 75%但是最后还有一个 INT_fiq ==1 && CPSR[6] == 0 这里
判断的问题,我试了 CPSR[7],CPSR[7]在 2、3 测试里都是 0,问题出在 INT_fiq 上有时候
读的进来有时候读不进来,后面我改成 INT_fiq ==0 && CPSR[6] == 0 二三测试结果正好反
过来,证明我状态设置没问题,但是为什么 INT_fiq 在我正确代码时,读进来全是 0 我就不
清楚了。
在组合预设代码和以前的程序时,没有遇到特别大的问题,不过由于许多 ppt 中的错误和预
设代码的本身结构问题,在仿真测试中修改了很久,比如,好几个状态都有漏信号的问题,
像 CPSR 修改的时候都没有发 Write_CPSR,只能根据状态功能来分析出还有哪些遗漏的信
号。再比如预设代码中的 CPSR 都是先修改 CPSR_IN,再通过若干 D 触发器来修改,但这
样的话,想通过 Rst 来把 CPSR 复位到 0x00000010 就很困难,最后解决办法是,将 Rst 接
入到每个 D 触发器复位端,给低 8 位对应的单独写了个特殊的 D 触发器,其复位不是复位
成 00 而是 10。
4、思考题:
步骤 6
1.中断隐指令----是指指令系统中没有的指令,它由 CPU 在中断响应周期自动完成。其功能是
保护程序断点、硬件关中断、向量地址送 PC(硬件向量法)或中断识别程序入口地址送 PC(软
件查询法)。
3. 31 中有 SP->MSP,不可以
4.前后有顺序关系
步骤 7
1.查表,然后逐行翻译。使用汇编器。linux 下命令是 as ,你可以 man as 来查看如何使用。
步骤 8
(1) INTA_irq/INTA_fiq 产 生 时 , 会 触 发 D 触 发 器 的 复 位 信 号 , 此 时 如 果 同 时 有
       EX_irq/EX_fiq,由于复位信号优先,所以还是会复位,关闭中断请求
(2)和(3) 结果相同,同时发起 EX_irq 和_EX_fiq 请求时,irq 会被 fiq 覆盖,最后只会
产生 INT_fiq 信号
步骤 9
3.D 触发器