简体   繁体   中英

counter program (assembly machine code) for MIPS processor using quartus 2

I have written a machine level code for a counter that should increment to 15 and then decrement to 10, once 15 is reached, and then reset to 0, once 10 is reached.

I have written this program in .mif files. I have used 2 .mif files, one for instruction memory and other for data memory.

I feel I have not written the jump instruction properly, as I'm not able to figure how to write the jump instruction.

This code below is the instruction memory code

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;

[/code]

The next one below is the data memory mif file

[code]

-- 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;

The program is not working as intended. It increments by 10 and then decrements randomly.

Pls help. I think I have not written the Jump instruction format properly.

First of all when working with FPGAs you should also consider that the CPU is not working correctly especially when you modified the HDL code of the CPU.

However if your CPU is a working MIPS CPU your program has the following errors:

  • What are the "lw r0,0(r0)" instructions (at addresses 0 and 0xB) for? On a real MIPS chip these instructions will access the memory at address 0 but then do nothing because on real MIPS chips r0 is read-only (it is always 0). If your FPGA-based implementation should really implement r0 as a register you cannot use "lw r0,0(r0)" to initialize r0 because r0 may contain another value than 0. In this case you must use something like "sub r0,r0,r0" to ensure r0 has the value 0.
  • "add r0,r0,r2" at address 6 will definitely not do what you expect - wheter r0 is hard-wired to 0 or implemented as real register.
  • You seem to have forgotten the "delay slots": A MIPS processor executes a jump or branch instruction with one cycle delay. An example: The "add" instruction at address 6 is executed even if the "beq" instruction at address 5 is branching. It is not allowed to place a jump instruction into a "delay slot" (to put a jump instruction after another jump instruction) - you violate this in addresses 7 and 8 that both contain a jump instruction. You also have to add a NOP instruction (eg "add r0,r0,r0") after the jump in address 0xC. It is best practice for beginners to add a NOP instruction after every jump and branch instruction so you can forget about delay slots.
  • Are you sure the "beq" instructions in addresses 5 and 8 are coded correctly? They seem to jump to addresses 7 and 0xA (or 6 and 9 ??) instead of 8 and 0xB.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM