From c7904fa9d96a9ae8b6f5e3daa9fc14bf912d5d29 Mon Sep 17 00:00:00 2001 From: yqszxx Date: Mon, 3 Feb 2020 16:18:20 +0800 Subject: [PATCH] Implement full width memory operations. --- instruction/instructionSet.go | 6 ++++ intf/processorIntf.go | 4 ++- main.go | 7 ++++- mem/mem.go | 23 +++++++++++++- processor/processor.go | 59 +++++++++++++++++++++++++++++++++++ 5 files changed, 96 insertions(+), 3 deletions(-) diff --git a/instruction/instructionSet.go b/instruction/instructionSet.go index 0e35afd..24b26ac 100644 --- a/instruction/instructionSet.go +++ b/instruction/instructionSet.go @@ -32,4 +32,10 @@ var InstructionSet = []Instruction{ SLTU, LW, SW, + LB, + LBU, + LH, + LHU, + SB, + SH, } diff --git a/intf/processorIntf.go b/intf/processorIntf.go index 2daa8d7..3bc525a 100644 --- a/intf/processorIntf.go +++ b/intf/processorIntf.go @@ -5,7 +5,9 @@ import ( ) const ( - Word = 3 + Byte = 1 + HalfWord = 2 + Word = 3 ) type ProcessorInterface interface { diff --git a/main.go b/main.go index 424cf8b..5009653 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "os" + "strings" "yars/instruction" "yars/mem" "yars/processor" @@ -16,7 +17,7 @@ func main() { log.SetFlags(log.Lshortfile) // only show file name and line number if len(os.Args) < 2 { - fmt.Println("Usage: yars elf_file") + fmt.Println("Usage: yars elf_file [d]") os.Exit(1) } @@ -27,6 +28,10 @@ func main() { loadElf(os.Args[1], &ram) // load executable to main memory log.Print(ram) // log the content of memory + if len(os.Args) > 2 && strings.Contains(os.Args[2], "d") { // dump only + os.Exit(0) + } + var regs reg.RegisterFile regs.Init() diff --git a/mem/mem.go b/mem/mem.go index b8aecdd..ae90541 100644 --- a/mem/mem.go +++ b/mem/mem.go @@ -2,6 +2,7 @@ package mem import ( "fmt" + "io/ioutil" "log" "os" "sort" @@ -41,6 +42,16 @@ func (mem *Memory) Read(address bv.BitVector) bv.BitVector { func (mem *Memory) WriteInt(address uint32, mask uint8, data uint32) { + // GPIO Logic + if address>>24 == 0xFE { + if data&1 == 1 { + fmt.Printf("!HIGH!\n") + } else { + fmt.Printf("!LOW!\n") + } + return + } + // Print Logic if address == 0xFFF8 { fmt.Printf("$0x%08X$\n", data) @@ -48,7 +59,7 @@ func (mem *Memory) WriteInt(address uint32, mask uint8, data uint32) { } // Done Logic - if address == 0xFFFC { + if (address >> 24) == 0xFF { fmt.Printf("!!!!!!!!!!!!!!!!!!!DONE#0x%08X#!!!!!!!!!!!!!!!!!!!\n", data) prof.Pr.Print() os.Exit(0) @@ -103,5 +114,15 @@ func (mem Memory) String() string { s = fmt.Sprintf("%s%08X\n", s, mem.data[k].value) } s = fmt.Sprintf("%s-========\n", s) + + for i := uint32(0); i < 4; i++ { + d := "" + for _, k := range keys { + d = fmt.Sprintf("%s%02X\n", d, uint8((mem.data[k].value)>>(8*i)&0xFF)) + } + file := fmt.Sprintf("/tmp/yarc_%d.txt", i) + _ = ioutil.WriteFile(file, []byte(d), 0644) + } + return s } diff --git a/processor/processor.go b/processor/processor.go index 618b320..dffc696 100644 --- a/processor/processor.go +++ b/processor/processor.go @@ -73,11 +73,48 @@ func (p *Processor) WriteReg(n bv.BitVector, data bv.BitVector) { func (p *Processor) ReadMemory(address bv.BitVector, mode uint8) bv.BitVector { var data bv.BitVector + var part int switch mode { case intf.Word: data = p.Mem.Read(address) + case intf.HalfWord: + if address.Test(1) { // address[1] == 1, high half + part = 1 + } else { // address[1] == 0, low half + part = 0 + } + address.Reset(1) + data = p.Mem.Read(address) + if part == 1 { // part == 1, high half + data = data.Sub(31, 16) + } else { // part == 0, low half + data = data.Sub(15, 0) + } + case intf.Byte: // byte is always aligned + if address.Test(1) && address.Test(0) { // address[1:0] == 0b11, highest byte + part = 3 + } else if address.Test(1) && !address.Test(0) { // address[1:0] == 0b10, second high byte + part = 2 + } else if !address.Test(1) && address.Test(0) { // address[1:0] == 0b01, second low byte + part = 1 + } else { // address[1:0] == 0b00, lowest byte + part = 0 + } + address.Reset(1) + address.Reset(0) + data = p.Mem.Read(address) + if part == 3 { // part == 3, highest byte + data = data.Sub(31, 24) + } else if part == 2 { // part == 2, second high byte + data = data.Sub(23, 16) + } else if part == 1 { // part == 1, second low byte + data = data.Sub(15, 8) + } else { // part == 0, lowest byte + data = data.Sub(7, 0) + } } + return data } @@ -85,5 +122,27 @@ func (p *Processor) WriteMemory(address bv.BitVector, data bv.BitVector, mode ui switch mode { case intf.Word: p.Mem.Write(address, bv.B("1111"), data) + case intf.HalfWord: + if address.Test(1) { // address[1] == 1, update high half + address.Reset(1) + p.Mem.Write(address, bv.B("1100"), bv.Cat(data, bv.Bv(16))) // fill low 16 bit0 with 0 + } else { // address[1] == 0, update low half + p.Mem.Write(address, bv.B("0011"), bv.Cat(bv.Bv(16), data)) // fill high 16 bits with 0 + } + case intf.Byte: // byte is always aligned + if address.Test(1) && address.Test(0) { // address[1:0] == 0b11, highest byte + address.Reset(1) + address.Reset(0) + p.Mem.Write(address, bv.B("1000"), bv.Cat(data, bv.Bv(24))) // fill low 24 bits with 0 + } else if address.Test(1) && !address.Test(0) { // address[1:0] == 0b10, second high byte + address.Reset(1) + p.Mem.Write(address, bv.B("0100"), bv.Cat(bv.Cat(bv.Bv(8), data), bv.Bv(16))) // fill high 8 bits and low 16 bits with 0 + } else if !address.Test(1) && address.Test(0) { // address[1:0] == 0b01, second low byte + address.Reset(0) + p.Mem.Write(address, bv.B("0010"), bv.Cat(bv.Cat(bv.Bv(16), data), bv.Bv(8))) // fill high 16 bits and low 8 bits with 0 + } else { // address[1:0] == 0b00, lowest byte + p.Mem.Write(address, bv.B("0001"), bv.Cat(bv.Bv(24), data)) // fill high 24 bits with 0 + } } + }