Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Architecture upgrade interrogation #1

Closed
alexandrebrg opened this issue Mar 3, 2021 · 6 comments
Closed

Architecture upgrade interrogation #1

alexandrebrg opened this issue Mar 3, 2021 · 6 comments

Comments

@alexandrebrg
Copy link

Hello!

I'm currently working the implementation of the memory into do-core1. But I have some interrogation about how to do things as for now I have a fork where I'm trying to implement the memory.

Firstly, I moved the whole process of instructions in a module Cpu, so we move away memory and cpu from main.rs. It might not be the best way to do that, can I have your mind on it ?

Then, the Cpu module has now load and store OpCode, but as we discussed my understanding of these OpCode was wrong, as the register should store the address (which match with the index of Vector in my memory module) of the memory and not the value from memory. It is not fixed as I don't know how to handle this problem, must the register store literally the index of the address or a reference ?

Thanks

@sameo
Copy link
Collaborator

sameo commented Mar 6, 2021

Hi @alexandrebrg

I'm currently working the implementation of the memory into do-core1. But I have some interrogation about how to do things as for now I have a fork where I'm trying to implement the memory.

Nice :)

Firstly, I moved the whole process of instructions in a module Cpu, so we move away memory and cpu from main.rs. It might not be the best way to do that, can I have your mind on it ?

It's definitely a good first step. We need to separate the fetch-decode-execute cycle of a typical CPU into separate entities at least.

As we can imagine supporting several versions of the do-core architecture, we could define a CPU interface that the do-core1 would implement. The interface would at least provide the 3 steps (fetch, decode, execute) as public methods. I can see that being implemented as a do-core crate, containing the interface definitions and implementation for different variants of the architecture (do-core1 would be the first variant). Our main.rs would then essentially become a wrapper around the do-core crate and could even take the architecture variant to emulate as a command line option.

Then, the Cpu module has now load and store OpCode, but as we discussed my understanding of these OpCode was wrong, as the register should store the address (which match with the index of Vector in my memory module) of the memory and not the value from memory. It is not fixed as I don't know how to handle this problem, must the register store literally the index of the address or a reference ?

As we started to discuss during our last session, memory can be seen as a byte addressable array. And do-core1 is going to follow that model.
It handles at most 4k (4096) bytes, which means memory can be represented as a memory: [u8; 4096] array.

Then, let's assume that R4 contains the value 0x100. The 0x0014 instruction, i.e. LD R0, R4 will copy memory[0x100] into R0.
In other words, LD Rn, Rm interprets the content of Rm as CPU memory address. Executing that instruction will copy the memory byte at that address into Rn.

Does that make more sense?

@alexandrebrg
Copy link
Author

do-core

Based on your vision, I assume we would need a workspace with on one hand the do-core crate and on the other hand the implementation of this crate. Moreover, the do-core interface would also implement properties like registers size, length and same for memory module.

Also, I understand this do-core crate will have multiple versions available, what kind of upgrades / changes will it get in the future ?

LD & ST Opcodes

It definitely makes sense, I will do update my code in this way. ty :)

Pull Request

About the pull request I'm wondering if it would make more sense to do a single PR with the new Opcodes and the changes about files architecture or do I need to split them up ?

On one hand we would have a single PR with two crates, do-core (containing the new Opcodes) and the wrapper in a workspace. On the other hand we would have at first PR containing a single crate with two modules (cpu & memory) containing the new Opcodes. And then another PR to change files architecture into the two crates withing a workspace. I feel like splitting into two PR would be cleaner to understand. Is this the proper way ?

@Hasenn
Copy link

Hasenn commented Mar 8, 2021

Hi
(LD and ST) To sum up and check if i understand it, this would behave like if our processor had 16 adress lines and 8 data lines ?

so that to read two bytes and fill up register R0 with the data at memory[*R1:*R1+1] we would need a left shift LSH (and an increment INC) and we'ld do something like

LD R0 R1 
LSH R0 8   ;; left shift r0 by 8 = 0b1000
INC R1 1   ;; increment R1 by 1
LD R2 R1   ;; load next byte into a register that shouldn't be holding anything usefull
OR R1 R2   ;; 0b[data1]00000000 OR 0b00000000[data2] = 0b[data1][data2]

Would LD clear the most significant byte of the value register if it loads a single byte ? would ST ignore the most significant byte when storing the value in memory?

@sameo
Copy link
Collaborator

sameo commented Mar 19, 2021

@Hasenn @alexandrebrg Does issue #5 answer those questions here? If so, please close this issue.

@Hasenn
Copy link

Hasenn commented Mar 19, 2021

It does for me,
@alexandrebrg can you close this ?

@alexandrebrg
Copy link
Author

Ok for me! I close

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants