전공 이야기/Digital System Design

#7 MIPS Pipeline Processor Design (5) - I/O, Constraints

[감자] 2023. 12. 26. 20:19

2. Verilog를 이용한 I/O 설계

 

2.1 7 Segment LED

7 segment LED 이용하여 Program Counter 값을 Hexadecimal 형식으로 출력하였다. 코드는 수업에서 제공된 코드를 이용하였다. Instantiation은 다음과 같다.

 

ss_drive SSEG (
        .clk(clk),
        .rst(rst),
        .data7(PC[31:28]),
        .data6(PC[27:24]),
        .data5(PC[23:20]),
        .data4(PC[19:16]),
        .data3(PC[15:12]),
        .data2(PC[11:8]),
        .data1(PC[7:4]),
        .data0(PC[3:0]),
        .mask(8'b11111111),
        .ssA(CA),
        .ssB(CB),
        .ssC(CC),
        .ssD(CD),
        .ssE(CE),
        .ssF(CF),
        .ssG(CG),
        .ssDP(),
        .AN(AN)
    );

 

 

 

2.2 UART

UART는 MIPS instruction을 진행하면서 변화하는 레지스터와 메모리의 변화를 모니터링하기 위해 사용하였다. 모니터링을 위한 문자들을 생성하여 TeraTerm을 이용하여 모니터링하는 것을 목표로 하여 구현하였다.

 

2.2.1  Instantiation

UART 소스코드는 수업에서 제공되는 소스코드를 사용하였고, UART에 데이터를 전달하는 모듈들을 추가하였다. Top 모듈에서의 Instantiation은 다음과 같다.

debounce DBNC0 (
        .clk(clk),
        .rst(rst),
        .din(din || tc),
        .tick(),
        .toggle(sig0)
    );
   
    debounce DBNC1 (
        .clk(clk),
        .rst(rst),
        .din(din),
        .tick(man_clk),
        .toggle()
    );
   
    clk_gen CLK (
        .clk_100MHz(clk),
        .rst(rst),
        .clk_low(clk_low)
    );
   
    count_char CNT (
        .clk(clk_low),
        .rst(rst),
        .trig(sig0),
        .sig(sig1),
        .tc(tc)
    );
 
  
    debounce DBNC2 (
        .clk(clk),
        .rst(rst),
        .din(sig1),
        .tick(sig2),
        .toggle()
    );
   
 
string_gen STR (
        .clk(sig2),
        .rst(rst),
        .reg0(t0),
        .PC(PC),
        .reg1(t1), .reg2(t2), .reg3(t3), .reg4(t4), .reg5(t5), .reg6(t6), .reg7(t7),
        .memory_8(mem8), .memory_9(mem9), .memory_10(mem10), .memory_11(mem11),
        .memory_12(mem12), .memory_13(mem13), .memory_14(mem14), .memory_15(mem15),
        .new(new),
        .char(data)
    );
   
 
    UART_top UART (
        .clk(clk),
        .rst(rst),
        .datain_ext(data),
        .dataout_ext(),
        .new_in(new),
        .new_out(),
        .error(error),
        .RxD(RxD),
        .TxD(TxD)
    );

 

 

DBNC0, DBNC1은 BTND의 입력을 MIPS의 클럭으로 사용하고 문자들을 보내는 신호로 사용하기 위한 Debouncing 모듈이다. debounce는 수업에서 제공되는 모듈을 사용하였다.

 

 

4.2.2. clk_gen

clk_gen 모듈은 UART에서 데이터를 보내는 시간을 보낼 수 있도록 느린 클럭 분주를 만들어주는 모듈이다. 소스코드는 다음과 같다.

module clk_gen(
    input clk_100MHz,
    input rst,
    output reg clk_low
    );
    integer cnt;
   
    always @(posedge clk_100MHz, posedge rst)
      if(rst) begin
        clk_low <= 0;
        cnt <= 0;
      end
      else if (cnt < 100000) begin
        cnt <= cnt + 1;
      end
      else begin
        cnt <= 0;
        clk_low = ~clk_low;
      end
endmodule

 

 

 

4.2.3. count_char

count_char 모듈은 string_gen 모듈에서 UART로 차례대로 데이터를 넘겨주도록 문자수와 동일한 수의 클럭을 만들어주는 모듈이다. clk_gen에서 느리게 형성된 클럭을 이용하여 UART에서 데이터를 완전히 보내고 난 뒤에 다음 데이터를 전송할 수 있도록 해주는 모듈이다.

 

module count_char(
    input clk,
    input rst,
    input trig,
    output sig,
    output tc
    );
 
    localparam INIT = 2'b00,
               CNT  = 2'b01,
               SIG  = 2'b10,
               COMP = 2'b11;
   
    reg [1:0] current_state, next_state;
    reg [8:0] char_cnt;
   
    always @(posedge clk, posedge rst)
      if(rst) begin
        current_state <= INIT;
      end
      else
        current_state <= next_state;
 
    always @* begin
      case(current_state)
        default : if(trig) next_state = CNT;
                  else next_state = INIT;
        CNT     : if(tc) next_state = COMP;
                  else next_state = SIG;
        SIG     : next_state = CNT;
        COMP    : next_state = INIT;
      endcase
    end
 
    always @(posedge clk, posedge rst) begin
      if(rst) begin
        char_cnt <= 0; 
      end else     
        case(current_state)
          default : begin char_cnt <= 0; end
          CNT     : begin char_cnt <= char_cnt + 1; end
          SIG     : begin char_cnt <= char_cnt; end
          COMP    : begin char_cnt <= 0; end
        endcase
      end
assign sig = (current_state != INIT) && (current_state != CNT) && (current_state == SIG || current_state == COMP);
    assign tc = (char_cnt == 274);
 
endmodule

 

 

 

 

4.2.4. String_gen

string_gen 모듈은 MIPS에서 온 데이터를 문자로 변환하여 UART로 전달하는 모듈이다. count_char로부터 신호가 들어오면 UART로 데이터를 보낸다.

 

module string_gen (
    input clk,
    input rst,
    input [31:0] reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7,
    input [31:0] memory_8, memory_9, memory_10, memory_11, memory_12, memory_13, memory_14, memory_15,
    output new,
    output reg [7:0] char
);
    reg [7:0] cnt;
    reg d0, d1, d2;
   
    always @(posedge clk, posedge rst)
      if(rst)
          char <= 8'h0;
      else
          case(cnt)
            0: char <= "$";
            1: char <= "8";
            2: char <= " ";
            3: char <= ":";
            4: char <= " ";
            5: if(reg0[31:28] < 4'ha) char <= reg0[31:28] + 8'h30;
               else char <= (reg0[31:28] + 8'h37);
            6: if(reg0[27:24] < 4'ha) char <= reg0[27:24] + 8'h30;
               else char <= (reg0[27:24] + 8'h37);
            7: if(reg0[23:20] < 4'ha) char <= reg0[23:20] + 8'h30;
               else char <= (reg0[23:20] + 8'h37);
            8: if(reg0[19:16] < 4'ha) char <= reg0[19:16] + 8'h30;
               else char <= (reg0[19:16] + 8'h37);
            9: if(reg0[15:12] < 4'ha) char <= reg0[15:12] + 8'h30;
               else char <= (reg0[15:12] + 8'h37);
            10: if(reg0[11:8] < 4'ha) char <= reg0[11:8] + 8'h30;
               else char <= (reg0[11:8] + 8'h37);
            11: if(reg0[7:4] < 4'ha) char <= reg0[7:4] + 8'h30;
               else char <= (reg0[7:4] + 8'h37);
            12: if(reg0[3:0] < 4'ha) char <= reg0[3:0] + 8'h30;
               else char <= (reg0[3:0] + 8'h37);
            13: char <= "\t";
            14: char <= "$";
            15: char <= "9";
            16: char <= " ";
            17: char <= ":";
            18: char <= " ";
            19: if(reg1[31:28] < 4'ha) char <= reg1[31:28] + 8'h30;
               else char <= (reg1[31:28] + 8'h37);
            20: if(reg1[27:24] < 4'ha) char <= reg1[27:24] + 8'h30;
               else char <= (reg1[27:24] + 8'h37);
            21: if(reg1[23:20] < 4'ha) char <= reg1[23:20] + 8'h30;
               else char <= (reg1[23:20] + 8'h37);
            22: if(reg1[19:16] < 4'ha) char <= reg1[19:16] + 8'h30;
               else char <= (reg1[19:16] + 8'h37);
            23: if(reg1[15:12] < 4'ha) char <= reg1[15:12] + 8'h30;
               else char <= (reg1[15:12] + 8'h37);
            24: if(reg1[11:8] < 4'ha) char <= reg1[11:8] + 8'h30;
               else char <= (reg1[11:8] + 8'h37);
            25: if(reg1[7:4] < 4'ha) char <= reg1[7:4] + 8'h30;
               else char <= (reg1[7:4] + 8'h37);
            26: if(reg1[3:0] < 4'ha) char <= reg1[3:0] + 8'h30;
               else char <= (reg1[3:0] + 8'h37);
            27: char <= "\t";
            28: char <= "$";
            29: char <= "1";
            30: char <= "0";
            31: char <= " ";
            32: char <= ":";
            33: char <= " ";
            34: if(reg2[31:28] < 4'ha) char <= reg2[31:28] + 8'h30;
               else char <= (reg2[31:28] + 8'h37);
            35: if(reg2[27:24] < 4'ha) char <= reg2[27:24] + 8'h30;
               else char <= (reg2[27:24] + 8'h37);
            36: if(reg2[23:20] < 4'ha) char <= reg2[23:20] + 8'h30;
               else char <= (reg2[23:20] + 8'h37);
            37: if(reg2[19:16] < 4'ha) char <= reg2[19:16] + 8'h30;
               else char <= (reg2[19:16] + 8'h37);
            38: if(reg2[15:12] < 4'ha) char <= reg2[15:12] + 8'h30;
               else char <= (reg2[15:12] + 8'h37);
            39: if(reg2[11:8] < 4'ha) char <= reg2[11:8] + 8'h30;
               else char <= (reg2[11:8] + 8'h37);
            40: if(reg2[7:4] < 4'ha) char <= reg2[7:4] + 8'h30;
               else char <= (reg2[7:4] + 8'h37);
            41: if(reg2[3:0] < 4'ha) char <= reg2[3:0] + 8'h30;
               else char <= (reg2[3:0] + 8'h37);
            42: char <= "\t";
            43: char <= "$";
            44: char <= "1";
            45: char <= "1";
            46: char <= " ";
            47: char <= ":";
            48: char <= " ";
            49: if(reg3[31:28] < 4'ha) char <= reg3[31:28] + 8'h30;
               else char <= (reg3[31:28] + 8'h37);
            50: if(reg3[27:24] < 4'ha) char <= reg3[27:24] + 8'h30;
               else char <= (reg3[27:24] + 8'h37);
            51: if(reg3[23:20] < 4'ha) char <= reg3[23:20] + 8'h30;
               else char <= (reg3[23:20] + 8'h37);
            52: if(reg3[19:16] < 4'ha) char <= reg3[19:16] + 8'h30;
               else char <= (reg3[19:16] + 8'h37);
            53: if(reg3[15:12] < 4'ha) char <= reg3[15:12] + 8'h30;
               else char <= (reg3[15:12] + 8'h37);
            54: if(reg3[11:8] < 4'ha) char <= reg3[11:8] + 8'h30;
               else char <= (reg3[11:8] + 8'h37);
            55: if(reg3[7:4] < 4'ha) char <= reg3[7:4] + 8'h30;
               else char <= (reg3[7:4] + 8'h37);
            56: if(reg3[3:0] < 4'ha) char <= reg3[3:0] + 8'h30;
               else char <= (reg3[3:0] + 8'h37);
            57: char <= "\r";
            58: char <= "\n";
            59: char <= "$";
            60: char <= "1";
            61: char <= "2";
            62: char <= " ";
            63: char <= ":";
            64: char <= " ";
            65: if(reg4[31:28] < 4'ha) char <= reg4[31:28] + 8'h30;
                else char <= (reg4[31:28] + 8'h37);
            66: if(reg4[27:24] < 4'ha) char <= reg4[27:24] + 8'h30;
               else char <= (reg4[27:24] + 8'h37);
            67: if(reg4[23:20] < 4'ha) char <= reg4[23:20] + 8'h30;
               else char <= (reg4[23:20] + 8'h37);
            68: if(reg4[19:16] < 4'ha) char <= reg4[19:16] + 8'h30;
               else char <= (reg4[19:16] + 8'h37);
            69: if(reg4[15:12] < 4'ha) char <= reg4[15:12] + 8'h30;
               else char <= (reg4[15:12] + 8'h37);
            70: if(reg4[11:8] < 4'ha) char <= reg4[11:8] + 8'h30;
               else char <= (reg4[11:8] + 8'h37);
            71: if(reg4[7:4] < 4'ha) char <= reg4[7:4] + 8'h30;
               else char <= (reg4[7:4] + 8'h37);
            72: if(reg4[3:0] < 4'ha) char <= reg4[3:0] + 8'h30;
               else char <= (reg4[3:0] + 8'h37);
            73: char <= "\t";
            74: char <= "$";
            75: char <= "1";
            76: char <= "3";
            77: char <= " ";
            78: char <= ":";
            79: char <= " ";
            80: if(reg5[31:28] < 4'ha) char <= reg5[31:28] + 8'h30;
                else char <= (reg5[31:28] + 8'h37);
            81: if(reg5[27:24] < 4'ha) char <= reg5[27:24] + 8'h30;
                else char <= (reg5[27:24] + 8'h37);
            82: if(reg5[23:20] < 4'ha) char <= reg5[23:20] + 8'h30;
               else char <= (reg5[23:20] + 8'h37);
            83: if(reg5[19:16] < 4'ha) char <= reg5[19:16] + 8'h30;
               else char <= (reg5[19:16] + 8'h37);
            84: if(reg5[15:12] < 4'ha) char <= reg5[15:12] + 8'h30;
               else char <= (reg5[15:12] + 8'h37);
            85: if(reg5[11:8] < 4'ha) char <= reg5[11:8] + 8'h30;
               else char <= (reg5[11:8] + 8'h37);
            86: if(reg5[7:4] < 4'ha) char <= reg5[7:4] + 8'h30;
               else char <= (reg5[7:4] + 8'h37);
            87: if(reg5[3:0] < 4'ha) char <= reg5[3:0] + 8'h30;
               else char <= (reg5[3:0] + 8'h37);
            88: char <= "\t";
            89: char <= "$";
            90: char <= "1";
            91: char <= "4";
            92: char <= " ";
            93: char <= ":";
            94: char <= " ";
            95: if(reg6[31:28] < 4'ha) char <= reg6[31:28] + 8'h30;
                else char <= (reg6[31:28] + 8'h37);
            96: if(reg6[27:24] < 4'ha) char <= reg6[27:24] + 8'h30;
                else char <= (reg6[27:24] + 8'h37);
            97: if(reg6[23:20] < 4'ha) char <= reg6[23:20] + 8'h30;
                else char <= (reg6[23:20] + 8'h37);
            98: if(reg6[19:16] < 4'ha) char <= reg6[19:16] + 8'h30;
                else char <= (reg6[19:16] + 8'h37);
            99: if(reg6[15:12] < 4'ha) char <= reg6[15:12] + 8'h30;
                else char <= (reg6[15:12] + 8'h37);
            100: if(reg6[11:8] < 4'ha) char <= reg6[11:8] + 8'h30;
                 else char <= (reg6[11:8] + 8'h37);
            101: if(reg6[7:4] < 4'ha) char <= reg6[7:4] + 8'h30;
                 else char <= (reg6[7:4] + 8'h37);
            102: if(reg6[3:0] < 4'ha) char <= reg6[3:0] + 8'h30;
                 else char <= (reg6[3:0] + 8'h37);
            103: char <= "\t";
            104: char <= "$";
            105: char <= "1";
            106: char <= "5";
            107: char <= " ";
            108: char <= ":";
            109: char <= " ";
            110: if(reg7[31:28] < 4'ha) char <= reg7[31:28] + 8'h30;
                 else char <= (reg7[31:28] + 8'h37);
            111: if(reg7[27:24] < 4'ha) char <= reg7[27:24] + 8'h30;
                 else char <= (reg7[27:24] + 8'h37);
            112: if(reg7[23:20] < 4'ha) char <= reg7[23:20] + 8'h30;
                 else char <= (reg7[23:20] + 8'h37);
            113: if(reg7[19:16] < 4'ha) char <= reg7[19:16] + 8'h30;
                 else char <= (reg7[19:16] + 8'h37);
            114: if(reg7[15:12] < 4'ha) char <= reg7[15:12] + 8'h30;
                 else char <= (reg7[15:12] + 8'h37);
            115: if(reg7[11:8] < 4'ha) char <= reg7[11:8] + 8'h30;
                 else char <= (reg7[11:8] + 8'h37);
            116: if(reg7[7:4] < 4'ha) char <= reg7[7:4] + 8'h30;
                 else char <= (reg7[7:4] + 8'h37);
            117: if(reg7[3:0] < 4'ha) char <= reg7[3:0] + 8'h30;
                 else char <= (reg7[3:0] + 8'h37);
            118: char <= "\r";
            119: char <= "\n";
            120: char <= "M";
            121: char <= "[";
            122: char <= "8";
            123: char <= "]";
            124: char <= " ";
            125: char <= ":";
            126: char <= " ";
            127: if(memory_8[31:28] < 4'ha) char <= memory_8[31:28] + 8'h30;
               else char <= (memory_8[31:28] + 8'h37);
            128: if(memory_8[27:24] < 4'ha) char <= memory_8[27:24] + 8'h30;
               else char <= (memory_8[27:24] + 8'h37);
            129: if(memory_8[23:20] < 4'ha) char <= memory_8[23:20] + 8'h30;
               else char <= (memory_8[23:20] + 8'h37);
            130: if(memory_8[19:16] < 4'ha) char <= memory_8[19:16] + 8'h30;
               else char <= (memory_8[19:16] + 8'h37);
            131: if(memory_8[15:12] < 4'ha) char <= memory_8[15:12] + 8'h30;
               else char <= (memory_8[15:12] + 8'h37);
            132: if(memory_8[11:8] < 4'ha) char <= memory_8[11:8] + 8'h30;
               else char <= (memory_8[11:8] + 8'h37);
            133: if(memory_8[7:4] < 4'ha) char <= memory_8[7:4] + 8'h30;
               else char <= (memory_8[7:4] + 8'h37);
            134: if(memory_8[3:0] < 4'ha) char <= memory_8[3:0] + 8'h30;
               else char <= (memory_8[3:0] + 8'h37);
            135: char <= "\t";
            136: char <= "M";
            137: char <= "[";
            138: char <= "9";
            139: char <= "]";
            140: char <= " ";
            141: char <= ":";
            142: char <= " ";
            143: if(memory_9[31:28] < 4'ha) char <= memory_9[31:28] + 8'h30;
               else char <= (memory_9[31:28] + 8'h37);
            144: if(memory_9[27:24] < 4'ha) char <= memory_9[27:24] + 8'h30;
               else char <= (memory_9[27:24] + 8'h37);
            145: if(memory_9[23:20] < 4'ha) char <= memory_9[23:20] + 8'h30;
               else char <= (memory_9[23:20] + 8'h37);
            146: if(memory_9[19:16] < 4'ha) char <= memory_9[19:16] + 8'h30;
               else char <= (memory_9[19:16] + 8'h37);
            147: if(memory_9[15:12] < 4'ha) char <= memory_9[15:12] + 8'h30;
               else char <= (memory_9[15:12] + 8'h37);
            148: if(memory_9[11:8] < 4'ha) char <= memory_9[11:8] + 8'h30;
               else char <= (memory_9[11:8] + 8'h37);
            149: if(memory_9[7:4] < 4'ha) char <= memory_9[7:4] + 8'h30;
               else char <= (memory_9[7:4] + 8'h37);
            150: if(memory_9[3:0] < 4'ha) char <= memory_9[3:0] + 8'h30;
               else char <= (memory_9[3:0] + 8'h37);
            151: char <= "\t";
            152: char <= "M";
            153: char <= "[";
            154: char <= "1";
            155: char <= "0";
            156: char <= "]";
            157: char <= " ";
            158: char <= ":";
            159: char <= " ";
            160: if(memory_10[31:28] < 4'ha) char <= memory_10[31:28] + 8'h30;
               else char <= (memory_10[31:28] + 8'h37);
            161: if(memory_10[27:24] < 4'ha) char <= memory_10[27:24] + 8'h30;
               else char <= (memory_10[27:24] + 8'h37);
            162: if(memory_10[23:20] < 4'ha) char <= memory_10[23:20] + 8'h30;
               else char <= (memory_10[23:20] + 8'h37);
            163: if(memory_10[19:16] < 4'ha) char <= memory_10[19:16] + 8'h30;
               else char <= (memory_10[19:16] + 8'h37);
            164: if(memory_10[15:12] < 4'ha) char <= memory_10[15:12] + 8'h30;
               else char <= (memory_10[15:12] + 8'h37);
            165: if(memory_10[11:8] < 4'ha) char <= memory_10[11:8] + 8'h30;
               else char <= (memory_10[11:8] + 8'h37);
            166: if(memory_10[7:4] < 4'ha) char <= memory_10[7:4] + 8'h30;
               else char <= (memory_10[7:4] + 8'h37);
            167: if(memory_10[3:0] < 4'ha) char <= memory_10[3:0] + 8'h30;
               else char <= (memory_10[3:0] + 8'h37);
            168: char <= "\t";
            169: char <= "M";
            170: char <= "[";
            171: char <= "1";
            172: char <= "1";
            173: char <= "]";
            174: char <= " ";
            175: char <= ":";
            176: char <= " ";
            177: if(memory_11[31:28] < 4'ha) char <= memory_11[31:28] + 8'h30;
               else char <= (memory_11[31:28] + 8'h37);
            178: if(memory_11[27:24] < 4'ha) char <= memory_11[27:24] + 8'h30;
               else char <= (memory_11[27:24] + 8'h37);
            179: if(memory_11[23:20] < 4'ha) char <= memory_11[23:20] + 8'h30;
               else char <= (memory_11[23:20] + 8'h37);
            180: if(memory_11[19:16] < 4'ha) char <= memory_11[19:16] + 8'h30;
               else char <= (memory_11[19:16] + 8'h37);
            181: if(memory_11[15:12] < 4'ha) char <= memory_11[15:12] + 8'h30;
               else char <= (memory_11[15:12] + 8'h37);
            182: if(memory_11[11:8] < 4'ha) char <= memory_11[11:8] + 8'h30;
               else char <= (memory_11[11:8] + 8'h37);
            183: if(memory_11[7:4] < 4'ha) char <= memory_11[7:4] + 8'h30;
               else char <= (memory_11[7:4] + 8'h37);
            184: if(memory_11[3:0] < 4'ha) char <= memory_11[3:0] + 8'h30;
               else char <= (memory_11[3:0] + 8'h37);
            185: char <= "\r";
            186: char <= "\n";
            187: char <= "M";
            188: char <= "[";
            189: char <= "1";
            190: char <= "2";
            191: char <= "]";
            192: char <= " ";
            193: char <= ":";
            194: char <= " ";
            195: if(memory_12[31:28] < 4'ha) char <= memory_12[31:28] + 8'h30;
               else char <= (memory_12[31:28] + 8'h37);
            196: if(memory_12[27:24] < 4'ha) char <= memory_12[27:24] + 8'h30;
               else char <= (memory_12[27:24] + 8'h37);
            197: if(memory_12[23:20] < 4'ha) char <= memory_12[23:20] + 8'h30;
               else char <= (memory_12[23:20] + 8'h37);
            198: if(memory_12[19:16] < 4'ha) char <= memory_12[19:16] + 8'h30;
               else char <= (memory_12[19:16] + 8'h37);
            199: if(memory_12[15:12] < 4'ha) char <= memory_12[15:12] + 8'h30;
               else char <= (memory_12[15:12] + 8'h37);
            200: if(memory_12[11:8] < 4'ha) char <= memory_12[11:8] + 8'h30;
               else char <= (memory_12[11:8] + 8'h37);
            201: if(memory_12[7:4] < 4'ha) char <= memory_12[7:4] + 8'h30;
               else char <= (memory_12[7:4] + 8'h37);
            202: if(memory_12[3:0] < 4'ha) char <= memory_12[3:0] + 8'h30;
               else char <= (memory_12[3:0] + 8'h37);
            203: char <= "\t";
            204: char <= "M";
            205: char <= "[";
            206: char <= "1";
            207: char <= "3";
            208: char <= "]";
            209: char <= " ";
            210: char <= ":";
            211: char <= " ";
            212: if(memory_13[31:28] < 4'ha) char <= memory_13[31:28] + 8'h30;
               else char <= (memory_13[31:28] + 8'h37);
            213: if(memory_13[27:24] < 4'ha) char <= memory_13[27:24] + 8'h30;
               else char <= (memory_13[27:24] + 8'h37);
            214: if(memory_13[23:20] < 4'ha) char <= memory_13[23:20] + 8'h30;
               else char <= (memory_13[23:20] + 8'h37);
            215: if(memory_13[19:16] < 4'ha) char <= memory_13[19:16] + 8'h30;
               else char <= (memory_13[19:16] + 8'h37);
            216: if(memory_13[15:12] < 4'ha) char <= memory_13[15:12] + 8'h30;
               else char <= (memory_13[15:12] + 8'h37);
            217: if(memory_13[11:8] < 4'ha) char <= memory_13[11:8] + 8'h30;
               else char <= (memory_13[11:8] + 8'h37);
            218: if(memory_13[7:4] < 4'ha) char <= memory_13[7:4] + 8'h30;
               else char <= (memory_13[7:4] + 8'h37);
            219: if(memory_13[3:0] < 4'ha) char <= memory_13[3:0] + 8'h30;
               else char <= (memory_13[3:0] + 8'h37);
            220: char <= "\t";
            221: char <= "M";
            222: char <= "[";
            223: char <= "1";
            224: char <= "4";
            225: char <= "]";
            226: char <= " ";
            227: char <= ":";
            228: char <= " ";
            229: if(memory_14[31:28] < 4'ha) char <= memory_14[31:28] + 8'h30;
               else char <= (memory_14[31:28] + 8'h37);
            230: if(memory_14[27:24] < 4'ha) char <= memory_14[27:24] + 8'h30;
               else char <= (memory_14[27:24] + 8'h37);
            231: if(memory_14[23:20] < 4'ha) char <= memory_14[23:20] + 8'h30;
               else char <= (memory_14[23:20] + 8'h37);
            232: if(memory_14[19:16] < 4'ha) char <= memory_14[19:16] + 8'h30;
               else char <= (memory_14[19:16] + 8'h37);
            233: if(memory_14[15:12] < 4'ha) char <= memory_14[15:12] + 8'h30;
               else char <= (memory_14[15:12] + 8'h37);
            234: if(memory_14[11:8] < 4'ha) char <= memory_14[11:8] + 8'h30;
               else char <= (memory_14[11:8] + 8'h37);
            235: if(memory_14[7:4] < 4'ha) char <= memory_14[7:4] + 8'h30;
               else char <= (memory_14[7:4] + 8'h37);
            236: if(memory_14[3:0] < 4'ha) char <= memory_14[3:0] + 8'h30;
               else char <= (memory_14[3:0] + 8'h37);
            237: char <= "\t";
            238: char <= "M";
            239: char <= "[";
            240: char <= "1";
            241: char <= "5";
            242: char <= "]";
            243: char <= " ";
            244: char <= ":";
            245: char <= " ";
            246: if(memory_15[31:28] < 4'ha) char <= memory_15[31:28] + 8'h30;
               else char <= (memory_15[31:28] + 8'h37);
            247: if(memory_15[27:24] < 4'ha) char <= memory_15[27:24] + 8'h30;
               else char <= (memory_15[27:24] + 8'h37);
            248: if(memory_15[23:20] < 4'ha) char <= memory_15[23:20] + 8'h30;
               else char <= (memory_15[23:20] + 8'h37);
            249: if(memory_15[19:16] < 4'ha) char <= memory_15[19:16] + 8'h30;
               else char <= (memory_15[19:16] + 8'h37);
            250: if(memory_15[15:12] < 4'ha) char <= memory_15[15:12] + 8'h30;
               else char <= (memory_15[15:12] + 8'h37);
            251: if(memory_15[11:8] < 4'ha) char <= memory_15[11:8] + 8'h30;
               else char <= (memory_15[11:8] + 8'h37);
            252: if(memory_15[7:4] < 4'ha) char <= memory_15[7:4] + 8'h30;
               else char <= (memory_15[7:4] + 8'h37);
            253: if(memory_15[3:0] < 4'ha) char <= memory_15[3:0] + 8'h30;
               else char <= (memory_15[3:0] + 8'h37);
            254: char <= "\r";
            255: char <= "\n";
            default: char <= "_";
          endcase
   
    always @(posedge clk, posedge rst) begin
      if(rst) cnt <= 8'd0;
      else begin
        cnt <= cnt + 1;
        if(cnt == 255)
          cnt <= 8'b0;
      end
    end
   
    assign new = clk;
 
endmodule

 

 

 

 

 

 

 

2.3 Audio

 

Audio 동작 설명

 

Audio를 이용하여 lw instruction에 의한 Hazard 발생시 주파수 440Hz의 "A"가 소리나도록 설계했다. 주파수는 클럭 주기에 카운터 값을 나눈 값으로 계산된다. 따라서 440Hz의 주파수를 갖기 위해 카운터 값은 100MHz / 440Hz = 227264가 되어야 한다. Duty cycle을 50%로 유지하기 위해 카운터 값의 절반, 즉 113632에서 스피커 값을 토글하여 사각파를 형성한다. 이러한 사각파는 소리를 생성한다.

 

module audio(clk, hazard, speaker);
  input clk, hazard;
  output speaker;
 
  reg [16:0] counter; //113632 00011011101111100000 17비트
  reg speaker;
 
  always @(posedge clk) begin
    if (counter == 113632) begin
        counter <= 0;
 
      if (hazard) begin
        speaker <= ~speaker;
      end
    end
 
    else begin
      counter <= counter + 1;
    end
  end
 
endmodule

 

 

 

 

 

2.4 Top module

 

Top module 동작 설명

 

사용자가 BTND 버튼을 누르면 MIPS_top 모듈에서는 Instruction을 한단계 진행하고 진행된 결과를 I/O 모듈들을 통해 데이터를 출력한다.

 

module display_top(
    input clk,
    input rst,
    input din,
    output TxD,
    output RxD,
    output error,
    output CA, CB, CC, CD, CE, CF, CG,
    output [7:0] AN,
    output [3:0] LED,
    output speaker
);
 
wire sig0, sig1, sig2;
wire man_clk;
wire [7:0] data;
wire new;
wire clk_low;
wire tc;
wire hazard;
wire [31:0] t0, t1, t2, t3, t4, t5, t6, t7;
wire [31:0] mem8, mem9, mem10, mem11, mem12, mem13, mem14, mem15;
wire [31:0] PC;
wire [1:0] forwardA, forwardB;
   
    ss_drive SSEG (
        .clk(clk),
        .rst(rst),
        .data7(PC[31:28]),
        .data6(PC[27:24]),
        .data5(PC[23:20]),
        .data4(PC[19:16]),
        .data3(PC[15:12]),
        .data2(PC[11:8]),
        .data1(PC[7:4]),
        .data0(PC[3:0]),
        .mask(8'b11111111),
        .ssA(CA),
        .ssB(CB),
        .ssC(CC),
        .ssD(CD),
        .ssE(CE),
        .ssF(CF),
        .ssG(CG),
        .ssDP(),
        .AN(AN)
    );
 
    MIPS MIPS (
        .clk(man_clk),
        .rst(rst),
        .ProgramCounter_Output(PC),
        .Register_8(t0), .Register_9(t1), .Register_10(t2), .Register_11(t3),
        .Register_12(t4), .Register_13(t5), .Register_14(t6), .Register_15(t7),
        .memory_8(mem8), .memory_9(mem9), .memory_10(mem10), .memory_11(mem11), .memory_12(mem12), .memory_13(mem13), .memory_14(mem14), .memory_15(mem15),
        .forward_A(forwardA), .forward_B(forwardB),
        .hazard(hazard)
    );
 
    debounce DBNC0 (
        .clk(clk),
        .rst(rst),
        .din(din || tc),
        .tick(),
        .toggle(sig0)
    );
   
    debounce DBNC1 (
        .clk(clk),
        .rst(rst),
        .din(din),
        .tick(man_clk),
        .toggle()
    );
   
    clk_gen CLK (
        .clk_100MHz(clk),
        .rst(rst),
        .clk_low(clk_low)
    );
   
    count_char CNT (
        .clk(clk_low),
        .rst(rst),
        .trig(sig0),
        .sig(sig1),
        .tc(tc)
    );
   
    debounce DBNC2 (
        .clk(clk), .rst(rst),
        .din(sig1),
        .tick(sig2),
        .toggle()
    );
   
    string_gen STR (
        .clk(sig2),
        .rst(rst),
        .reg0(t0),
        .PC(PC),
        .reg1(t1), .reg2(t2), .reg3(t3), .reg4(t4), .reg5(t5), .reg6(t6), .reg7(t7),
        .memory_8(mem8), .memory_9(mem9), .memory_10(mem10), .memory_11(mem11),
        .memory_12(mem12), .memory_13(mem13), .memory_14(mem14), .memory_15(mem15),
        .new(new),
        .char(data)
    );
   
    UART_top UART (
        .clk(clk),
        .rst(rst),
        .datain_ext(data),
        .dataout_ext(),
        .new_in(new),
        .new_out(),
        .error(error),
        .RxD(RxD),
        .TxD(TxD)
    );
   
    audio AUIDO (
        .clk(clk),
        .hazard(hazard),
        .speaker(speaker)
    );
   
    assign LED[0] = forwardA[0];
    assign LED[1] = forwardA[1];
    assign LED[2] = forwardB[0];
    assign LED[3] = forwardB[1];
endmodule

 

 

 

 

2.5 Constraints

 

Constraints 설명

 

 해당 Processor를 설계하기 위해서 FPGA(Xc7a100t-2csg324c), UART, Audio가 사용되었고, 다음은 사용한 FPGA의 규격에 따른 Constraints file이다. Fpga 내부의 button BTNC와 BTND를 각각 리셋 신호(rst)와 다음 state를 확인하기 위한 버튼으로 사용하였으며, 현재의 Program Counter 값을 표기하기 위한 Seven Segment, forwarding을 표기하기 위한 LED가 사용되었으며, forwarding이 아닌 lw instruction에서의 hazard 발생시 소리를 출력하는 Audio Amplifier, 안전한 오디오 사용을 위하여 Configuration Settings을 추가하였다. 레지스터 및 메모리값을 직접 눈으로 확인할 수 있도록 하는 UART 통신을 위해 TxD와 RxD 또한 포함시켰다.

 

## This file is a general .xdc for the Nexys A7-100T
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
 
## Clock signal
set_property -dict {PACKAGE_PIN E3 IOSTANDARD LVCMOS33} [get_ports clk]
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports clk]
 
## Configuration Settings
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.5 [current_design]
 
## LEDs
set_property -dict { PACKAGE_PIN H17   IOSTANDARD LVCMOS33 } [get_ports { LED[0] }];
set_property -dict { PACKAGE_PIN K15   IOSTANDARD LVCMOS33 } [get_ports { LED[1] }];
set_property -dict { PACKAGE_PIN J13   IOSTANDARD LVCMOS33 } [get_ports { LED[2] }];
set_property -dict { PACKAGE_PIN N14   IOSTANDARD LVCMOS33 } [get_ports { LED[3] }];
 
##Buttons
set_property -dict {PACKAGE_PIN N17 IOSTANDARD LVCMOS33} [get_ports { rst }]
set_property -dict { PACKAGE_PIN P18   IOSTANDARD LVCMOS33 } [get_ports { din }];
 
##PWM Audio Amplifier
set_property -dict { PACKAGE_PIN A11   IOSTANDARD LVCMOS33 } [get_ports { speaker }];
 
##7 segment display
set_property -dict { PACKAGE_PIN T10   IOSTANDARD LVCMOS33 } [get_ports { CA }];
set_property -dict { PACKAGE_PIN R10   IOSTANDARD LVCMOS33 } [get_ports { CB }];
set_property -dict { PACKAGE_PIN K16   IOSTANDARD LVCMOS33 } [get_ports { CC }];
set_property -dict { PACKAGE_PIN K13   IOSTANDARD LVCMOS33 } [get_ports { CD }];
set_property -dict { PACKAGE_PIN P15   IOSTANDARD LVCMOS33 } [get_ports { CE }];
set_property -dict { PACKAGE_PIN T11   IOSTANDARD LVCMOS33 } [get_ports { CF }];
set_property -dict { PACKAGE_PIN L18   IOSTANDARD LVCMOS33 } [get_ports { CG }];
 
set_property -dict { PACKAGE_PIN J17   IOSTANDARD LVCMOS33 } [get_ports { AN[0] }];
set_property -dict { PACKAGE_PIN J18   IOSTANDARD LVCMOS33 } [get_ports { AN[1] }];
set_property -dict { PACKAGE_PIN T9    IOSTANDARD LVCMOS33 } [get_ports { AN[2] }];
set_property -dict { PACKAGE_PIN J14   IOSTANDARD LVCMOS33 } [get_ports { AN[3] }];
set_property -dict { PACKAGE_PIN P14   IOSTANDARD LVCMOS33 } [get_ports { AN[4] }];
set_property -dict { PACKAGE_PIN T14   IOSTANDARD LVCMOS33 } [get_ports { AN[5] }];
set_property -dict { PACKAGE_PIN K2    IOSTANDARD LVCMOS33 } [get_ports { AN[6] }];
set_property -dict { PACKAGE_PIN U13   IOSTANDARD LVCMOS33 } [get_ports { AN[7] }];
 
##USB-RS232 Interface
set_property -dict { PACKAGE_PIN C4    IOSTANDARD LVCMOS33 } [get_ports { RxD }];
set_property -dict { PACKAGE_PIN D4    IOSTANDARD LVCMOS33 } [get_ports { TxD }];