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
実行するには
以下を実行
実行
アセンブラを機械語に変換
HEXファイルに変換
HEXファイルをVerilogのMEMに読み込ませる
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ファイルがおかしいみたいです。
アセンブラ→機械語への変換に何か設定が必要なのでしょう。
所感
ここで終わりにしますか・・・
この記事が気に入ったらサポートをしてみませんか?