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 }]; |
'전공 이야기 > Digital System Design' 카테고리의 다른 글
#8 MIPS Pipeline Processor Design (6) - Simulation, 결론 (2) | 2023.12.26 |
---|---|
#6 MIPS Pipeline Processor Design (4) - Hazard, Top module (0) | 2023.12.26 |
#5 MIPS Pipeline Processor Design (3) - Pipes, Control (0) | 2023.12.26 |
#4 MIPS Pipeline Processor Design (2) - ID, EX, MEM, WB (1) | 2023.12.26 |
#3 MIPS Pipeline Processor Design (1) - IF Stage, Sub Unit (0) | 2023.12.26 |