программа-счетчик (машинный код на ассемблере) для процессора MIPS с использованием quartus 2

Я написал код машинного уровня для счетчика, который должен увеличиваться до 15, а затем уменьшаться до 10 при достижении 15, а затем сбрасываться до 0 при достижении 10.

Я написал эту программу в файлах .mif. Я использовал 2 файла .mif, один для памяти инструкций, а другой для памяти данных.

Я чувствую, что неправильно написал инструкцию прыжка, так как не могу понять, как написать инструкцию прыжка.

Этот код ниже является кодом памяти инструкций

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, а затем случайным образом уменьшается.

Пожалуйста, помогите. Я думаю, что неправильно записал формат инструкции Jump.


person bobdxcool    schedule 27.10.2013    source источник


Ответы (1)


Прежде всего, при работе с FPGA вы также должны учитывать, что ЦП работает неправильно, особенно когда вы модифицировали HDL-код ЦП.

Однако, если ваш процессор является рабочим процессором MIPS, ваша программа имеет следующие ошибки:

  • Для чего нужны инструкции "lw r0,0(r0)" (по адресам 0 и 0xB)? На реальном чипе MIPS эти инструкции будут обращаться к памяти по адресу 0, но затем ничего не делают, потому что на реальных чипах MIPS r0 доступен только для чтения (он всегда равен 0). Если ваша реализация на основе FPGA действительно должна реализовывать r0 как регистр, вы не можете использовать «lw r0,0(r0)» для инициализации r0, потому что r0 может содержать значение, отличное от 0. В этом случае вы должны использовать что-то вроде «sub r0,r0 ,r0", чтобы убедиться, что r0 имеет значение 0.
  • «добавить r0, r0, r2» по адресу 6 определенно не сделает то, что вы ожидаете, независимо от того, жестко ли r0 подключен к 0 или реализован как реальный регистр.
  • Вы, кажется, забыли «слоты задержки»: процессор MIPS выполняет инструкцию перехода или ветвления с задержкой в ​​один цикл. Пример: инструкция «добавить» по адресу 6 выполняется, даже если инструкция «beq» по адресу 5 является ветвящейся. Не разрешается помещать инструкцию перехода в «слот задержки» (помещать инструкцию перехода после другой инструкции перехода) — вы нарушаете это в адресах 7 и 8, которые оба содержат инструкцию перехода. Вы также должны добавить инструкцию NOP (например, «добавить r0,r0,r0») после перехода по адресу 0xC. Для новичков рекомендуется добавлять инструкцию NOP после каждой инструкции перехода и ветвления, чтобы вы могли забыть о слотах задержки.
  • Вы уверены, что инструкции «beq» в адресах 5 и 8 закодированы правильно? Кажется, они перескакивают на адреса 7 и 0xA (или 6 и 9 ??) вместо 8 и 0xB.
person Martin Rosenau    schedule 28.10.2013