見出し画像

RISC-V(RV32IM.v)とは

背景

専用回路で素数を計算するのはコスパ的に意味がないでしょう。
では、RISC-Vで計算すればいいのでは?
過去の記事

RISC-V

RISC-Vの最小構成(RV32I.v)では乗算命令がありません。では乗算命令があるのは?
コードはここから

コードは

module RV32IM(input wire clock, input wire reset_n, output wire [31:0] pc_out, output wire [31:0] op_out, output wire [31:0] alu_out, output wire [8:0] uart_out);
// Copyright (c) 2020 asfdrwe (asfdrwe@gmail.com)
// SPDX-License-Identifier: MIT
  // REGISTER
  reg [31:0] pc;
  assign pc_out = pc; // for DEBUG
  reg [31:0] regs[0:31];

  // MEMORY 64KB 
  reg [7:0] mem[0:16'hffff]; // MEMORY 64KB
  initial $readmemh("test.hex", mem); // MEMORY INITIALIZE 

  // UART OUTPUT and CYCLE COUNTER
  reg [8:0] uart = 9'b0; // uart[8] for output sign, uart[7:0] for data
  assign uart_out = uart;
  localparam [31:0] UART_MMIO_ADDR = 32'h0000_fff0; // ADDRESS 0xfff0 for UART DATA
  localparam [31:0] UART_MMIO_FLAG = 32'h0000_fff1; // ADDRESS 0xfff1 for UART FLAG
  reg [31:0] counter = 32'b0;
  localparam [31:0] COUNTER_MMIO_ADDR = 32'h0000_fff4; // ADDRESS 0xfff4 for COUNTER

  // FETCH
  wire [31:0] opcode;
  assign opcode = {mem[pc + 3], mem[pc + 2], mem[pc + 1], mem[pc]}; // little endian
  assign op_out = opcode; // for DEBUG

  // DECODE
  wire [4:0] r_addr1, r_addr2, w_addr;
  wire [31:0] imm;
  wire [4:0] alucon;
  wire [2:0] funct3;
  wire op1sel, op2sel, mem_rw, rf_wen;
  wire [1:0] wb_sel, pc_sel;

  wire [6:0] op;
  assign op = opcode[6:0];

  localparam [6:0] RFORMAT       = 7'b0110011;
  localparam [6:0] IFORMAT_ALU   = 7'b0010011;
  localparam [6:0] IFORMAT_LOAD  = 7'b0000011;
  localparam [6:0] SFORMAT       = 7'b0100011;
  localparam [6:0] SBFORMAT      = 7'b1100011;
  localparam [6:0] UFORMAT_LUI   = 7'b0110111;
  localparam [6:0] UFORMAT_AUIPC = 7'b0010111;
  localparam [6:0] UJFORMAT      = 7'b1101111;
  localparam [6:0] IFORMAT_JALR  = 7'b1100111;
  localparam [6:0] ECALLEBREAK   = 7'b1110011;
  localparam [6:0] FENCE         = 7'b0001111;
  localparam [6:0] MULDIV        = 7'b0110011;

  assign r_addr1 = (op == UFORMAT_LUI) ? 5'b0 : opcode[19:15];
  assign r_addr2 = opcode[24:20];
  assign w_addr =  opcode[11:7];

  assign imm[31:20] = ((op == UFORMAT_LUI) || (op == UFORMAT_AUIPC)) ? opcode[31:20] : 
		      (opcode[31] == 1'b1) ? 12'hfff : 12'b0;
  assign imm[19:12] = ((op == UFORMAT_LUI) || (op == UFORMAT_AUIPC) || (op == UJFORMAT)) ? opcode[19:12] :
                      (opcode[31] == 1'b1) ? 8'hff : 8'b0;
  assign imm[11] = (op == SBFORMAT) ? opcode[7] :
                   ((op == UFORMAT_LUI) || (op == UFORMAT_AUIPC)) ? 1'b0 :
                   (op == UJFORMAT) ? opcode[20] : opcode[31];
  assign imm[10:5] = ((op == UFORMAT_LUI) || (op == UFORMAT_AUIPC)) ? 6'b0 : opcode[30:25];
  assign imm[4:1] = ((op == IFORMAT_ALU) || (op == IFORMAT_LOAD) || (op == IFORMAT_JALR) || (op == UJFORMAT)) ? opcode[24:21] :
		    ((op == SFORMAT) || (op == SBFORMAT)) ? opcode[11:8] : 4'b0;
  assign imm[0] = ((op == IFORMAT_ALU) || (op == IFORMAT_LOAD) || (op == IFORMAT_JALR)) ? opcode[20] :
		  (op == SFORMAT) ? opcode[7] : 1'b0;

  assign alucon = ((op == RFORMAT) || (op == MULDIV)) ? {opcode[30], opcode[25], opcode[14:12]} :
                  ((op == IFORMAT_ALU) && (opcode[14:12] == 3'b101)) ? {opcode[30], opcode[25], opcode[14:12]} : // SRLI or SRAI
                  (op == IFORMAT_ALU) ? {2'b00, opcode[14:12]} : 5'b0;
  assign funct3 = opcode[14:12];
  assign op1sel = ((op == SBFORMAT) || (op == UFORMAT_AUIPC) || (op == UJFORMAT)) ? 1'b1 : 1'b0;
  assign op2sel = ((op == RFORMAT) || (op == MULDIV)) ? 1'b0 : 1'b1;
  assign mem_rw = (op == SFORMAT) ? 1'b1 : 1'b0;
  assign wb_sel = (op == IFORMAT_LOAD) ? 2'b01 :
                  ((op == UJFORMAT) || (op == IFORMAT_JALR)) ? 2'b10 : 2'b00;
  assign rf_wen = (((op == RFORMAT) && ({opcode[31],opcode[29:25]} == 6'b000000)) ||
                   ((op == MULDIV) && ({opcode[31:25]} == 7'b000001)) ||
                   ((op == IFORMAT_ALU) && (({opcode[31:25], opcode[14:12]} == 10'b00000_00_001) || ({opcode[31], opcode[29:25], opcode[14:12]} == 9'b0_000_00_101) ||  // SLLI or SRLI or SRAI
                                            (opcode[14:12] == 3'b000) || (opcode[14:12] == 3'b010) || (opcode[14:12] == 3'b011) || (opcode[14:12] == 3'b100) || (opcode[14:12] == 3'b110) || (opcode[14:12] == 3'b111))) ||
                   (op == IFORMAT_LOAD) || (op == UFORMAT_LUI) || (op == UFORMAT_AUIPC) || (op == UJFORMAT) || (op == IFORMAT_JALR)) ? 1'b1 : 1'b0;
  assign pc_sel = (op == SBFORMAT) ? 2'b01 :
                  ((op == UJFORMAT) || (op == IFORMAT_JALR) || (op == ECALLEBREAK)) ? 2'b10 : 2'b00;

  // EXECUTION

  // REGISTER READ                  
  wire [31:0] r_data1, r_data2;
  assign r_data1 = (r_addr1 == 5'b00000) ? 32'b0 : regs[r_addr1]; 
  assign r_data2 = (r_addr2 == 5'b00000) ? 32'b0 : regs[r_addr2]; 

  // SELECTOR  
  wire [31:0] s_data1, s_data2;
  assign s_data1 = (op1sel == 1'b1) ? pc : r_data1;
  assign s_data2 = (op2sel == 1'b1) ? imm : r_data2;

  // ALU
  wire [31:0] alu_data;
  reg [63:0] tmpalu;

  function [31:0] ALU_EXEC( input [4:0] control, input [31:0] data1, input [31:0] data2);
    case(control)
    5'b00000: // ADD ADDI (ADD)
      ALU_EXEC = data1 + data2;
    5'b10000: // SUB (SUB)
      ALU_EXEC = data1 - data2;
    5'b00001: // SLL SLLI (SHIFT LEFT (LOGICAL))
      ALU_EXEC = data1 << data2[4:0];
    5'b00010: // SLT SLTI (SET_ON_LESS_THAN (SIGNED))
      ALU_EXEC = ($signed(data1) < $signed(data2)) ? 32'b1 :32'b0;
    5'b00011: // SLTU SLTUI (SET_ON_LESS_THAN (UNSIGNED))
      ALU_EXEC = (data1 < data2) ? 32'b1 :32'b0;
    5'b00100: // XOR XORI (XOR)
      ALU_EXEC = data1 ^ data2;
    5'b00101: // SRL SRLI (SHIFT RIGHT (LOGICAL))
      ALU_EXEC = data1 >> data2[4:0];
    5'b10101: // SRA SRAI (SHIFT RIGHT (ARITHMETIC))
      ALU_EXEC = $signed(data1[31:0]) >>> data2[4:0];
    5'b00110: // OR ORI (OR)
      ALU_EXEC = data1 | data2;
    5'b00111: // AND ANDI (AND)
      ALU_EXEC = data1 & data2;
    5'b01000: // MUL (MULTIPLE)
      ALU_EXEC = data1 * data2;
    5'b01001: begin // MULH (MULTIPLE)
      tmpalu = $signed(data1) * $signed(data2);
      ALU_EXEC = $signed(tmpalu) >>> 32;
    end
    5'b01010: begin // MULHSU (MULTIPLE)
      tmpalu = $signed(data1) * $signed({1'b0, data2});
      ALU_EXEC = tmpalu >> 32;
    end
    5'b01011: begin // MULHU (MULTIPLE)
      tmpalu = data1 * data2;
      ALU_EXEC = tmpalu >> 32;
    end
    5'b01100: // DIV (DIVIDE)
      ALU_EXEC = (data2 == 32'b0) ? 32'hffff_ffff : 
                 ((data1 == 32'h8000_0000) && (data2 == 32'hffff_ffff)) ? 32'h8000_0000 : $signed($signed(data1) / $signed(data2));
    5'b01101: // DIVU (DIVIDE)
      ALU_EXEC = (data2 == 32'b0) ? 32'hffff_ffff : (data1 / data2);
    5'b01110: // REM (DIVIDE REMINDER)
      ALU_EXEC = (data2 == 32'b0) ? data1 : 
                 ((data1 == 32'h8000_0000) && (data2 == 32'hffff_ffff)) ? 32'h0 : $signed($signed(data1) % $signed(data2));
    5'b01111: // REMU (DIVIDE REMINDER)
      ALU_EXEC = (data2 == 32'b0) ? data1 : (data1 % data2);
    default: // ILLEGAL
      ALU_EXEC = 32'b0;
    endcase
  endfunction

  assign alu_data = ALU_EXEC(alucon, s_data1, s_data2);
  assign alu_out = alu_data; // for DEBUG

  // BRANCH
  wire pc_sel2;

  function BRANCH_EXEC( input [2:0] branch_op, input [31:0] data1, input [31:0] data2, input [1:0] pc_sel);
    case(pc_sel)
    2'b00: // PC + 4
      BRANCH_EXEC = 1'b0;
    2'b01: begin // BRANCH
      case(branch_op)
      3'b000: // BEQ
        BRANCH_EXEC = (data1 == data2) ? 1'b1 : 1'b0;
      3'b001: // BNE
        BRANCH_EXEC = (data1 != data2) ? 1'b1 : 1'b0;
      3'b100: // BLT
        BRANCH_EXEC = ($signed(data1) < $signed(data2)) ? 1'b1 : 1'b0;
      3'b101: // BGE
        BRANCH_EXEC = ($signed(data1) >= $signed(data2)) ? 1'b1 : 1'b0;
      3'b110: // BLTU
        BRANCH_EXEC = (data1 < data2) ? 1'b1 : 1'b0;
      3'b111: // BGEU
        BRANCH_EXEC = (data1 >= data2) ? 1'b1 : 1'b0;
      default: // ILLEGAL
        BRANCH_EXEC = 1'b0;
      endcase
    end 
    2'b10: // JAL JALR
      BRANCH_EXEC = 1'b1;
    default: // ILLEGAL
      BRANCH_EXEC = 1'b0;
    endcase
  endfunction

  assign pc_sel2 = BRANCH_EXEC(funct3, r_data1, r_data2, pc_sel);

  // MEMORY 
  wire [2:0] mem_val;
  wire [31:0] mem_data;
  wire [31:0] mem_addr;
  assign mem_val = funct3;
  assign mem_addr = alu_data;
  
  // MEMORY READ
  assign mem_data = (mem_rw == 1'b1) ? 32'b0 : // when MEMORY WRITE, the output from MEMORY is 32'b0
		    ((mem_val == 3'b010) && (mem_addr == COUNTER_MMIO_ADDR)) ? counter : // MEMORY MAPPED IO for CLOCK CYCLE COUNTER
		    ((mem_val[1:0] == 2'b00) && (mem_addr == UART_MMIO_FLAG)) ? 8'b1 : // MEMORY MAPPED IO for UART FLAG(always enabled(8'b1))
                     (mem_val == 3'b000) ?  (mem[mem_addr][7] == 1'b1 ? {24'hffffff, mem[mem_addr]} : {24'h000000, mem[mem_addr]}) : // LB
                     (mem_val == 3'b001) ?  (mem[mem_addr + 1][7] == 1'b1 ? {16'hffff, mem[mem_addr + 1], mem[mem_addr]} : {16'h0000, mem[mem_addr + 1], mem[mem_addr]}) : // LH
                     (mem_val == 3'b010) ? {mem[mem_addr + 3], mem[mem_addr + 2], mem[mem_addr + 1], mem[mem_addr]} : // LW
                     (mem_val == 3'b100) ? {24'h000000, mem[mem_addr]} : // LBU
                     (mem_val == 3'b101) ? {16'h0000, mem[mem_addr + 1], mem[mem_addr]} : // LHU
                                           32'b0;
  // MEMORY WRITE
  always @(posedge clock) begin
    if (mem_rw == 1'b1) begin
      case (mem_val)
        3'b000: // SB
          mem[mem_addr] <= #1 r_data2[7:0];
        3'b001: // SH
          {mem[mem_addr + 1], mem[mem_addr]} <= #1 r_data2[15:0];
        3'b010: // SW
          {mem[mem_addr + 3], mem[mem_addr + 2], mem[mem_addr + 1], mem[mem_addr]} <= #1 r_data2;
        default: begin end // ILLEGAL
      endcase
    end
    // MEMORY MAPPED IO to UART
    if ((mem_rw == 1'b1) && (mem_addr == UART_MMIO_ADDR)) begin
      uart <= #1 {1'b1, r_data2[7:0]};
    end else begin
      uart <= #1 9'b0;
    end
  end

  // REGISTER WRITE BACK
  wire [31:0] w_data;
  assign w_data = (wb_sel == 2'b00) ? alu_data : 
                  (wb_sel == 2'b01) ? mem_data :
                  (wb_sel == 2'b10) ? pc + 4 : 32'b0; // ILLEGAL
  always @(posedge clock) begin
    if ((rf_wen == 1'b1) && (w_addr != 5'b00000))
      regs[w_addr] <= #1 w_data;
  end

  // NEXT PC
  wire [31:0] next_pc;
  assign next_pc = (pc_sel2 == 1'b1) ? {alu_data[31:1], 1'b0} : pc + 4;

  // NEXT PC WRITE BACK and CYCLE COUNTER
  always @(posedge clock or negedge reset_n) begin
   if (!reset_n) begin
      pc <= 32'b0;
      counter <= 32'b0;
    end else begin
      pc <= #1 next_pc; 
      counter <= counter + 1;
    end
  end
endmodule

素数を計算するアセンブラは?

やりますか

.section .data
    primes: .space 40        # 素数リスト用のスペースを確保 (4バイト * 10個)
    current_num: .word 2      # チェックする現在の数
    max_num: .word 10         # チェックする最大の数

.section .text
.global _start

# UART Base Address (仮定)
UART_MMIO_ADDR: .word 0x0000fff0
UART_MMIO_FLAG: .word 0x0000fff1

_start:
    # ジャンプ命令でアドレス 0x000100E8 に飛ぶ
    la x5, 0x000100E8
    jr x5

# アドレス 0x000100E8 から開始するプログラム
.section .text
.org 0x000100E8

start_program:
    # UART初期化
    la x1, UART_MMIO_ADDR
    li x2, 0x00          # 制御レジスタの初期化(例として0を書き込む)
    sw x2, 0(x1)
    
    # レジスタ初期化
    la x10, primes             # x10 = primes (素数リストの先頭アドレス)
    la x11, current_num        # x11 = current_num のアドレス
    lw x12, 0(x11)             # x12 = current_num の値 (2)
    li x13, 2                  # x13 = 初期除数 (2)
    la x14, max_num            # x14 = max_num のアドレス
    lw x15, 0(x14)             # x15 = max_num の値 (10)

next_num:
    lw x12, 0(x11)             # x12 = current_num の値を再読み込み
    li x13, 2                  # x13 = 初期除数にリセット
    la x16, primes             # x16 = primes の先頭アドレス
    li x17, 1                  # x17 = フラグ (1 = 素数, 0 = 素数でない)

check_prime:
    mul x18, x13, x13          # x18 = x13 * x13
    bge x18, x12, store_prime  # x18 >= x12 ならば store_prime へ

    # x19 = x12 / x13
    li x19, 0                  # x19 = 0 (quotient)
    mv x20, x12                # x20 = x12 (dividend)
divide_loop:
    blt x20, x13, after_divide # if x20 < x13, jump to after_divide
    sub x20, x20, x13          # x20 = x20 - x13
    addi x19, x19, 1           # x19 = x19 + 1
    j divide_loop
after_divide:
    mul x21, x19, x13          # x21 = x19 * x13
    sub x22, x12, x21          # x22 = x12 - x21
    beq x22, x0, not_prime     # if x22 == 0, x12 is not a prime

    addi x13, x13, 1           # x13 = x13 + 1
    j check_prime              # check_prime に戻る
    
store_prime:
    beq x17, x0, next_num      # x17 が 0 ならば次の数へ
    sw x12, 0(x10)             # x10 の位置に x12 を保存
    addi x10, x10, 4           # x10 を次の位置に進める
    
    # 素数をUARTに送信
    la x1, UART_MMIO_FLAG      # UARTフラグのアドレスをロード
wait_uart:
    lw x2, 0(x1)               # UARTのフラグを読み込む
    li x3, 1                   # フラグ値 1 を設定
    bne x2, x3, wait_uart      # フラグが1でない場合、待機
    la x1, UART_MMIO_ADDR      # UARTデータのアドレスをロード
    sw x12, 0(x1)              # UARTデータレジスタに送信するデータを書き込む

next_num_increment:
    addi x12, x12, 1           # x12 = x12 + 1 (次の数へ)
    sw x12, 0(x11)             # current_num に新しい x12 を保存
    blt x12, x15, next_num     # x12 < max_num ならば next_num へ
    j end                      # max_num を超えたら終了
    
not_prime:
    li x17, 0                  # x17 = 0 (素数でない)
    j next_num_increment       # 次の数へ

end:
    li a7, 10                  # ecall 10 (終了)
    ecall
    

実行するには

以下を実行

riscv64-unknown-elf-as -o primes.o primes.S
riscv64-unknown-elf-ld -o primes primes.o
riscv64-unknown-elf-objcopy -O verilog primes primes.hex
iverilog -o tb_RV32IM.vvp tb_RV32IM.v RV32IM.v
vvp tb_RV32IM.vvp

実行

  1. アセンブラを機械語に変換

  2. HEXファイルに変換

  3. HEXファイルをVerilogのMEMに読み込ませる

  4. RTLシミュレーションを実行

RISC-VのRTLは動作させるために多少書き換えてます。

出力結果

At time             16877066, PC = 000100e4, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877076, PC = 000100e8, Opcode = 0000fff0, ALU_out = xxxxxxxx, UART_out = 000000000
At time             16877086, PC = 000100ec, Opcode = 0000fff1, ALU_out = xxxxxxxx, UART_out = 000000000
At time             16877096, PC = 000100f0, Opcode = 000102b7, ALU_out = 00010000, UART_out = 000000000
At time             16877106, PC = 000100f4, Opcode = 0e82829b, ALU_out = 000100e0, UART_out = 000000000
At time             16877116, PC = 000100f8, Opcode = 00028067, ALU_out = 00010000, UART_out = 000000000
At time             16877126, PC = 00010000, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877136, PC = 00010004, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877146, PC = 00010008, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877156, PC = 0001000c, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877166, PC = 00010010, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877176, PC = 00010014, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877186, PC = 00010018, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877196, PC = 0001001c, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877206, PC = 00010020, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877216, PC = 00010024, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877226, PC = 00010028, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877236, PC = 0001002c, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877246, PC = 00010030, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877256, PC = 00010034, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877266, PC = 00010038, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877276, PC = 0001003c, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877286, PC = 00010040, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877296, PC = 00010044, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877306, PC = 00010048, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877316, PC = 0001004c, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877326, PC = 00010050, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877336, PC = 00010054, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877346, PC = 00010058, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877356, PC = 0001005c, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877366, PC = 00010060, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877376, PC = 00010064, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877386, PC = 00010068, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877396, PC = 0001006c, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877406, PC = 00010070, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877416, PC = 00010074, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877426, PC = 00010078, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877436, PC = 0001007c, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877446, PC = 00010080, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877456, PC = 00010084, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877466, PC = 00010088, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877476, PC = 0001008c, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877486, PC = 00010090, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877496, PC = 00010094, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877506, PC = 00010098, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877516, PC = 0001009c, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877526, PC = 000100a0, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877536, PC = 000100a4, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877546, PC = 000100a8, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877556, PC = 000100ac, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877566, PC = 000100b0, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877576, PC = 000100b4, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877586, PC = 000100b8, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877596, PC = 000100bc, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877606, PC = 000100c0, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877616, PC = 000100c4, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877626, PC = 000100c8, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877636, PC = 000100cc, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877646, PC = 000100d0, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877656, PC = 000100d4, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877666, PC = 000100d8, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877676, PC = 000100dc, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877686, PC = 000100e0, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877696, PC = 000100e4, Opcode = xxxxxxxx, ALU_out = 00000000, UART_out = 000000000
At time             16877706, PC = 000100e8, Opcode = 0000fff0, ALU_out = xxxxxxxx, UART_out = 000000000
At time             16877716, PC = 000100ec, Opcode = 0000fff1, ALU_out = xxxxxxxx, UART_out = 000000000
At time             16877726, PC = 000100f0, Opcode = 000102b7, ALU_out = 00010000, UART_out = 000000000
At time             16877736, PC = 000100f4, Opcode = 0e82829b, ALU_out = 000100e0, UART_out = 000000000
At time             16877746, PC = 000100f8, Opcode = 00028067, ALU_out = 00010000, UART_out = 000000000

まだ何か間違えてます。
MEMファイルがおかしいみたいです。
アセンブラ→機械語への変換に何か設定が必要なのでしょう。

所感

ここで終わりにしますか・・・

この記事が気に入ったらサポートをしてみませんか?