0

15 にインクリメントし、15 に達すると 10 にデクリメントし、10 に達すると 0 にリセットするカウンターのマシン レベル コードを作成しました。

私はこのプログラムを .mif ファイルに書きました。2 つの .mif ファイルを使用しました。1 つは命令メモリ用、もう 1 つはデータ メモリ用です。

ジャンプ命令の書き方がわからないので、ジャンプ命令を正しく書いていない気がします。

以下のこのコードは、命令メモリコードです

enter code here





--
-- Instruction Memory Initialization File
--
-- Instrucion Format:
--
-- R-Type: <6-bit Opcode>,<5-bit rs>,<5-bit rt>,<5-bit rd>,<5-bit shamt>,<6-bit funct>
--    bits   (31-26)       (25-21)     (20-16)    (15-11)     (10-6)       (5-0)
--
-- I-Type: <6-bit Opcode>,<5-bit rs>,<5-bit rt>,<16-bit Address> 
--   bits     (31-26)      (25-21)   (20-16)     (15-0)


--File format:
-- Hex Address 3 hex nibbles (12 bits) : bit31 ...... bit0;

WIDTH=32;
DEPTH=1024;

ADDRESS_RADIX=HEX;
DATA_RADIX=BIN;

CONTENT BEGIN
--Hex Address :   bit31..........................bit0;
--   |             |                              |
    000       :    10001100000000000000000000000000;
--                 |____||___||___||______________|
--                   |     |    |          |
--                   lw, rs=0, rt=0,   offset=0 
-- This is the first instruction that get's executed
-- in mips_ss CPU in DE0-Nano.
-- This is a lw instructioni. It loads r0 with data from
-- data memory location 0. Data memory location 0 is 
-- preloaded with 0 , see DRAM.mif.
--
    001       :    10001100000000010000000000000100;
--                 |____||___||___||______________|
--                   |     |    |          |
--                   lw, rs=0, rt=1,   offset=4 
-- This is a lw instructioni. It loads r1 with data from
-- data memory location 4. Data memory location 4 is 
-- preloaded with 0, see DRAM.mif.
--
    002       :    10001100000000100000000000001000;
--                 |____||___||___||______________|
--                   |     |    |          |
--                   lw, rs=0, rt=2,   offset=8 
-- This is a lw instructioni. It loads r2 with data from
-- data memory location 8. Data memory location 8 is 
-- preloaded with 1, see DRAM.mif.
    003       :    10001100000000110000000000001100;
--                 |____||___||___||______________|
--                   |     |    |          |
--                   lw, rs=0, rt=3,   offset=12 
-- This is a lw instructioni. It loads r3 with data from
-- data memory location 8. Data memory location 8 is 
-- preloaded with 10, see DRAM.mif.
    004       :    10001100000001000000000000010000;
--                 |____||___||___||______________|
--                   |     |    |          |
--                   lw, rs=0, rt=4,   offset=16 
-- This is a lw instructioni. It loads r4 with data from
-- data memory location 8. Data memory location 8 is 
-- preloaded with 15, see DRAM.mif.
--
    005       :    00010000100000000000000000000000;
--                 |____||___||___||______________|
--                   |     |    |         |             
--                  beq,rs=4,rt=0,  offset exit loop(addr:008)

    006       :    00000000010000000000000000100000;
--                 |____||___||___||___||___||____|
--                   |     |    |    |    |    |         
--                 R-type,rs=2,rt=0,rd=0,---,f=add 
-- Add instructions (r-type, opcode=0, funct=100000) 
-- add       => rd = rs + rt
-- Therefore => r0 = r2 + r0

    007       :    00001000000000000000000000000101;
--                 |____||________________________|
--                   |               |             
--                 jump, Target address:address(005) 
-- Decrementing to 10
    008       :    00010000011000000000000000000000;
--                 |____||___||___||______________|
--                   |     |    |         |             
--                  beq,rs=3,rt=0,  offset to exit loop(addr:00B)

    009       :    00000000010000010010100000100010;
--                 |____||___||___||___||___||____|
--                   |     |    |    |    |    |         
--                 R-type,rs=2,rt=1,rd=5,---,f=sub 
-- sub instructions (r-type, opcode=0, funct=100010) 
-- add       => rd = rs - rt
-- Therefore => r4 = r1 - r2
    00A       :    00001000000000000000000000001000;
--                 |____||________________________|
--                   |               |             
--                 jump, Target address:address(addr:008)
-- Reloading when r0 == 10
    00B       :    10001100000000000000000000000000;
--                 |____||___||___||______________|
--                   |     |    |          |
--                   lw, rs=0, rt=0,   offset=0 
-- This is a lw instructioni. It loads r0 with data from
-- data memory location 4. Data memory location 0 is 
-- preloaded with 0, see DRAM.mif.

    00C       :    00001000000000000000000000000101;
--                 |____||________________________|
--                   |               |             
--                 jump, Target address:address(addr:005)

END;

[/コード]

次は、データ メモリの mif ファイルです。

[コード]

-- Data Memory Initialization File
--

--File format:
-- Hex Address 3 hex nibbles (12 bits) : bit31 ...... bit0;

WIDTH=32;
DEPTH=1024;

ADDRESS_RADIX=HEX;
DATA_RADIX=BIN;

CONTENT BEGIN
    000       :    00000000000000000000000000000000;
    001       :    00000000000000000000000000000000;
-- 1
    002       :    00000000000000000000000000000001;
-- 10
    003       :    00000000000000000000000000001010;
-- 15
    004       :    00000000000000000000000000001111;
END;

プログラムが意図したとおりに機能していません。10 ずつ増加し、ランダムに減少します。

助けてください。ジャンプ命令のフォーマットをきちんと書いていないと思います。

4

1 に答える 1

0

まず、FPGA を使用する場合、特に CPU の HDL コードを変更した場合、CPU が正しく動作していないことを考慮する必要があります。

ただし、CPU が動作中の MIPS CPU である場合、プログラムには次のエラーがあります。

  • "lw r0,0(r0)" 命令 (アドレス 0 と 0xB) は何のためですか? 実際の MIPS チップでは、これらの命令はアドレス 0 のメモリにアクセスしますが、実際の MIPS チップでは r0 が読み取り専用 (常に 0) であるため、何もしません。FPGA ベースの実装で実際に r0 をレジスタとして実装する必要がある場合、r0 には 0 以外の値が含まれる可能性があるため、「lw r0,0(r0)」を使用して r0 を初期化することはできません。この場合、「sub r0,r0」のようなものを使用する必要があります。 ,r0" を使用して、r0 の値が 0 であることを確認します。
  • アドレス 6 で「r0、r0、r2 を追加」しても、r0 が 0 に配線されているか、実際のレジスタとして実装されているかに関係なく、期待どおりの結果は得られません。
  • 「遅延スロット」を忘れているようです。MIPS プロセッサは、1 サイクルの遅延でジャンプまたは分岐命令を実行します。例:5番地のbeq命令が分岐しているにも関わらず、6番地のadd命令が実行されます。ジャンプ命令を「遅延スロット」に配置すること (ジャンプ命令を別のジャンプ命令の後に配置すること) は許可されていません。ジャンプ命令を含むアドレス 7 と 8 でこれに違反します。また、アドレス 0xC へのジャンプの後に NOP 命令を追加する必要があります (例: "add r0,r0,r0")。遅延スロットを忘れることができるように、すべてのジャンプおよび分岐命令の後に NOP 命令を追加することは、初心者にとってベスト プラクティスです。
  • アドレス 5 と 8 の「beq」命令は正しくコーディングされていますか? 8 と 0xB ではなく、アドレス 7 と 0xA (または 6 と 9 ??) にジャンプするようです。
于 2013-10-28T09:25:19.750 に答える