2
\$\begingroup\$

LDI R16, 0x25 --> E 2 0 5 --> 1110 0010 0000 0101

Apparently, in AVR, the code and data are stored separately and each area (code, data area) is accessed by a unique bus.

Now since the Program Counter contains the address to the next instruction which in this case is LDI: PC --> E (PC points to 'E')

My question is, when loading the data parts (instruction) within 1 clock cycle, well.. opcode 'E' is directly referred to by the PC. How does the CPU find the data portion (0010 0000 0101)?

Or have I got it entirely wrong and are the 2 bytes (E + 0010 0000 0101) of the instruction the 'code' and kept as a single unit in the code area. In which case what is the data area - is that for instructions that use memory addresses: eg,

LDS R10, $FFFF Here code is the bytes for the entire instruction and the data is probably populated by the assembler from some variable assignment?

Why then does he say:

In Sections 2-2 and 2-3, you learned about data memory space and how to use the STS and LDS instructions. ?Then the CPU wants to execute the ?LDS Rn,k? instruction, it puts k on the address bus of the Data Bus, and receives data through the data bus. For example, to execute ?LDS R20, 0x90?, the CPU puts 0x90 on the address bus. The location $90 is in the SRAM (see Figure 2-4). Thus, the SRAM puts the contents of location $90 on the data bus. The CPU gets the contents of location $90 through the data bus and puts it in R20.

WTH? Could someone clearly explain AVR code/data bus architecture and how instructions are fetched and executed?

Harvard architecture in AVR

\$\endgroup\$
  • \$\begingroup\$ Immediate operands are stored as part of the instruction, as with almost all architectures. \$\endgroup\$ – Ignacio Vazquez-Abrams Jun 10 '16 at 12:59
1
\$\begingroup\$

Okay so: LDS R10, $FFFF is the instruction and it's resolved into bytes (2 or whatever bytes) and the entire thing is stored in the 'code'.

AVR 'code' and 'data' are like C, code segment and data segment. The compiler allocates storage for variables/string literals in 'data' (not constants).

The CPU slurps the entire instruction (2 bytes) using the Program Counter register. It decodes it (extract the register/address/opcode info) and executes the instruction by latching the address onto the address bus, and taking the value off the data bus into the register R10.

\$\endgroup\$
0
\$\begingroup\$

The architecture is about as simple as it can be for a Harvard system:

There's program memory (flash) accessible via one bus, and there's data memory (RAM) accessible via the other bus.

The program bus is 16 bits wide, i.e. up to 16 bits can be read from program memory at once.

All instruction opcodes are 16 bits wide, so every instruction can be fetched in one step. However, instructions like LDS consist of the instruction opcode (16 bits) and an additional argument of 16 bits, e.g. the RAM address to read from. This means that first the instruction opcode is fetched from program memory and decoded; during decoding, the CPU detects that the instruction has an argument, so another 16 bit read from program memory is performed to fetch the argument's value. (That's also the reason why LDS takes two CPU clock cycles, while LDI needs only one, and LPM needs three. In AVRs, the speed of the flash memory is what mostly limits the CPU clock frequency.)

Then the CPU wants to execute the LDS Rn,k instruction, it puts k on the address bus of the Data Bus, and receives data through the data bus.

This is also straight forward: After k is read from program memory, the RAM data from the address denoted by k needs to be fetched. This is done by putting the address to be read, the value of k, on the address bus of the RAM bus, which responds on the data bus of the RAM bus with the data fetched from the RAM address previously sent to the address bus.

Basically: You want to read from a RAM address, send the address you want to the address bus then read the data from the data bus.

\$\endgroup\$
0
\$\begingroup\$

are the 2 bytes (E + 0010 0000 0101) of the instruction the 'code' and kept as a single unit in the code area. In which case what is the data area - is that for instructions that use memory addresses

Yes, this is basically right. I think the key difference you're missing is the addressing modes. LDI uses "immediate" mode addressing, which means that the value is specified in the instruction itself and therefore is taken from the code area. This is true of immediate mode on basically every architecture.

LDS uses "direct" addressing. A value is encoded into the instruction, but that value is not loaded into the target register - instead it is put out on the address bus to specify which value from the data area should be loaded.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy