We may need to recompile the hardware/software interface when compiling for TLM model as compared to the device driver installed in an OS or ROM firmware.
For a 'mid-level model', differences might be minor and so implemented in C preprocessor.
Device driver access to a DMA controller might be changed as follows:
#define DMACONT_BASE (0xFFFFCD00) // Or other memory map value. #define DMACONT_SRC_REG 0 #define DMACONT_DEST_REG 4 #define DMACONT_LENGTH_REG 8 // These are the offsets of the addressable registers #define DMACONT_STATUS_REG 12 #ifdef ACTUAL_FIRMWARE // For real system and lower-level models: // Store via processor bus to DMACONT device register #define DMACONT_WRITE(A, D) (*(DMACONT_BASE+A*4)) = (D) #define DMACONT_READ(A) (*(DMACONT_BASE+A*4)) #else // For high-level TLM modelling: // Make a direct subroutine call from the firmware to the DMACONT model. #define DMACONT_WRITE(A, D) dmaunit.slave_write(A, D) #define DMACONT_READ(A) dmaunit.slave_read(A) #endif // The device driver will make all hardware accesses to the unit using these macros. // When compiled native, the calls will directly invoke the behavioural model, bypassing the bus model.Behavioural model example (the one-channel DMA controller from earlier):
// Behavioural model of
// slave side: operand register r/w.
uint32 src, dest, length;
bool busy, int_enable;
u32_t status() { return (busy << 31)
| (int_enable << 30); }
u32_t slave_read(u32_t a)
{
return (a==0)? src: (a==4) ? dest:
(a==8) ? (length) : status();
}
void slave_write(u32_t1 a, u32_t d)
{
if (a==0) src=d;
else if (a==4) dest=d;
else if (a==8) length = d;
else if (a==12)
{ busy = d >> 31;
int_enable = d >> 30; }
}
| // Bev model of bus mastering portion.
while(1)
{
waituntil(busy);
while (length-- > 0)
mem.write(dest++, mem.read(src++));
busy = 0;
}
|
Like to make interrupt output with an RTL-like continuous assignment:
interrupt = int_enable & !busy;But this will need a thread to run it, so this code must be placed in its own C macro that is inlined at all points where the supporting expressions might change.
A full example is in the `ethercrc.zip' folder on the course web site (and unzipped on PWF).
Alternatively, it is also possible to use the workstation VM system to trap calls from natively-compiled firmware to hardware.
| 4: (C) 2008-13, DJ Greaves, University of Cambridge, Computer Laboratory. |