Backward Up Forward

3.3 Processor Model

Processor and I/O bus models provide one of the most compelling reasons for using SMI. Thanks to the prevalence of stand-alone and embedded micro-processors in modern digital design, nearly all designs either contain or interface to one or more processors. It is not uncommon for library or part suppliers to provide Verilog models of the processor cells and components they supply. However, although these models may function correctly, they may often suffer from several shortcomings.

However, vendor-supplied cycle accurate models of processors embedded in the design under test must be used to generate test vectors.

Implementing a processor model entirely in Verilog (i.e. without using the PLI) implies that all test code is either written in Verilog or read from a file. The PCI bus model from Synopsys is a good example of this type of Verilog model. If all the test code is written in Verilog, typically in terms of Verilog task calls, then each test generates a simulation executable, which consumes both time and disk space. If the test code is read from a file, then the sequence of operations is fixed by the order of commands in the file, which is very inflexible. In either case, the code can only be used with the hardware simulation. It cannot be easily converted into real processor code or binary code used by the vendors processor model.

Ideally a processor model would accept the same C source code used to generate the binary code required to run on the vendors processor model and the physical processor hardware. The model would allow the test code to be symbolically debugged as it was running, or more accurately, as it was being simulated. The test code could then be debugged in a friendly environment before converting it into binary for the generation of test vectors or to run on the physical hardware. In addition, any code running on the physical hardware that generates an error could be ported back to the simulation environment where the cause of the error could be tracked down.

This section shows how to construct a processor model with all of the advantages listed above. However, this processor model is not cycle accurate; it does not simulate individual processor instructions it simulates I/O operations. Externally, cycle accurate and non-cycle accurate models are indistinguishable as they both conform to the bus protocol specifications of the processor. To implement a processor model using SMI, a test processes execution thread is used to simulate the processors execution thread. The hardware model instance performs a fetch-execute loop. It fetches an I/O operation from the software model instance and then executes it by driving the I/O bus signals according to the bus protocol. The test process dynamically generates processor I/O operations for the software model instance to send to the hardware model instance. The hardware model instance also sends the results of I/O read operations back to the test process via the software model instance. In this way, a method call made by the test process that closely resembles an I/O read has the following implementation.

  1. The software model instance stores the I/O read operation until the hardware model instance fetches it.
  2. The hardware model instance fetches the I/O read operation.
  3. The hardware model instance drives the I/O bus to perform the I/O read operation.
  4. The hardware model instance send a message to the software model instance containing the data read by the I/O read operation.
  5. The software model instance returns the data to the test process.

The processor model presented in this section also supports a hardware interrupt supported by an interrupt service routine. The I/O operations generated by the test process are temporarily paused while a small sequence of I/O operations generated by a pre-registered interrupt service routine are performed.

3.3.1 Hardware Model

The hardware model presented in this section models a simple micro-processor controlling a bus. A bus is a collection of signals that take values in accordance with a set of rules known as a bus protocol. In our example any number of target devices may be connected to the I/O bus in addition to the processor itself. The processor bus protocol specifies the sequence of signal transitions required to perform bus operations. Two bus operations are supported by the processor model; I/O write and I/O read. Both operations are initiated by the processor model. The I/O write operation transfers a data word from the processor to a target device. The I/O read operation transfers a data word from a target device to the processor. An address value that uniquely specifies the target device is output during each bus operation. Target devices are pre-configured to respond to non-overlapping address ranges and hence only one target device can take part in each bus operation. In addition, an interrupt signal can be driven by any target device at any time, causing the processor to execute code from an interrupt service routine.

Figure 3.3.1(a): Example Processor Model

The "clock" signal is used to synchronize the other signals that form the processor bus. Processor outputs change state at the rising edge of the clock; inputs are sampled on the rising edge of the clock. The processor bus is non-multiplexed, i.e. it contains separate "address" and "data" buses. The "data" bus is bi-directional and is only driven by the processor during I/O write operations. During an I/O write bus operation, the "write" command signal is set, and the "address" and "data" buses are driven to the appropriate values. The I/O write bus operation completes when the target device responds by asserting the "ready" signal". During an I/O read bus operation, the "read" command signal is set, and the "address" bus is driven to the appropriate value. The I/O read bus operation completes when the target device responds by asserting the "ready" signal" and driving the "data" bus to the appropriate value. During an idle cycle, neither the "write" or "read" command lines are asserted. The processor hardware model performs a sequence of bus operations under the direction of the software model and the test process. However, this sequence can be temporarily interrupted by asserting the "interrupt" signal, causing the software model to execute a specific sequence of bus operations called the interrupt service routine.

SMI Model: processor
Parameter: INSTANCE SMI instance name.
ADDR_WIDTH Sets the width of the processor address bus in bits.
DATA_WIDTH Sets the width of the processor data bus in bits.
Clock Domains: clock All signals switch on posedge "clock" unless stated otherwise.
Inputs: clock Clock signal.
interrupt When this signal is asserted, the software model instance will execute code from the interrupt service routine, interrupting the standard instruction stream.
ready This signal is asserted on the completion of an I/O operation.
Outputs: read This signal is asserted during an I/O read operation.
write This signal is asserted during an I/O write operation.
address[ADDR_WIDTH] This bus transmits the address parameter of an I/O operation and remains constant during a the I/O operation.
Inouts: data[DATA_WIDTH] This bus transmits the data parameter of an I/O write operation and remains constant during a the I/O write operation. During an I/O read operation, this bus becomes and input, receiving the data read by the operation.

Figure 3.3.1(b): Example Processor Timing

At start up, The SMI model is initialized then the bus widths are used to configure the software model by sending a "Configure" message.

During simulation, the processor model loops through an instruction fetch-execute cycle. The instruction fetch is implemented by sending an "Instruction" message to the software model instance. The reply message is decoded and the associated instruction is executed. There are four possible reply messages "Idle", "In", "Out" and "IRet". The "Idle" message causes the processor to perform an idle bus cycle. The "In" and "Out" messages cause the processor to perform an I/O read and an I/O write bus operation respectively. At the end of an I/O read bus operation, the data read from the target device is transmitted to the software model instance using a "Data" message. Both the I/O read and I/O write bus operations require multiple clock cycles to complete and require a response from a target device.

The "interrupt" signal is polled between instructions and an "Interrupt" message is sent if the signal is asserted and interrupt handling is enabled. Once this message has been sent, interrupt handling is disabled and will not be re-enabled until the software model instance returns an "IRet" message in response to an "Instruction" message.

Source: processor.v

3.3.2 Message Protocol

Name Type Content Reply
Configure HS-W [CPU_CONFIGURE, <addr>, <data>]
Instruction HS-R [CPU_INSTRUCTION] Idle/Out/In/IRet
Idle SM-R [CPU_IDLE]
Out SM-R [CPU_OUT, <addr>, <data>]
In SM-R [CPU_IN, <addr>] Data
Data HS-W [CPU_DATA, <data>]
Interrupt HS-W [CPU_INTERRUPT]
IRet SM-R [CPU_IRET]

Constants "CPU_CONFIGURE", "CPU_INSTRUCTION", "CPU_DATA" and "CPU_INTERRUPT" are used to identify the four types of message, "Configure", "Instruction", "Data" and "Interrupt", that can be sent from the hardware to the software model instance. Constants "CPU_IDLE", "CPU_IN", "CPU_OUT" and "CPU_IRET" are used to identify the four types of message, "Idle", "In", "Out" and "IRet", that can be sent from the software to the hardware model instance.

After each hardware model instance initializes it sends a "Configure" message to the software model instance, specifying the bit width of the address and data buses. During simulation, the hardware model instance performs a sequence of bus operations corresponding to messages sent from the software model instance. The fetch-execute loop begins with the hardware model sending an "Instruction" message to the software model instance. The software model instance replies with an "Idle", "In", "Out" or "IRet" message. The hardware model instance then performs the bus operation corresponding to the this reply message. The "In" and "Out" messages contain an address field used to set the address bus during the bus operation. The "Out" message also contains a data field used to set the data bus during the bus operation. A "Data" message is used to send data from the hardware to the software model instance after it has been read by the hardware model instance performing the bus operation corresponding to an "In" message. An "Interrupt" message can be send from the hardware to the software model instance to indicate that an interrupt has been requested by an external device.

Message: Configure
Content: addr Sets the width of the processor address bus in bits.
data Sets the width of the processor data bus in bits.
Description: This message is sent once, at simulation start-up, before any of the other message types have been sent. The message contents, the width of the address and data buses, are to format I/O transactions.

Message: Instruction
Reply: Idle/Out/In/IRet The software model returns one of the listed message types.
Description: This message fetches a new instruction for the processor to execute. The software model has an instruction waiting to be returned back to the hardware model when this message is sent. The reply is decoded and the associated action performed.

Message: Idle
Description: This message instructs the processor hardware model to perform an idle cycle, i.e. wait until the next clock cycle before fetching the next instruction without performing a bus operation.

Message: Out
Content: addr Address written to by the bus write operation.
data Data written to the address by the bus write operation.
Description: This message instructs the processor hardware model to perform a bus write operation. The model will perform the sequence of signal transitions necessary to write data to the address specified by the message contents.

Message: In
Content: addr Address read by the bus read operation.
Reply: Data Returns the data read by the bus read operation.
Description: This message instructs the processor hardware model to perform a bus read operation. The model will perform the sequence of signal transitions necessary to read data from the address specified by the message contents. A Data message is send to the software model containing the data value read.

Message: Data
Content: data Data read by the preceding bus read operation.
Description: This message returns the data value read by the preceding bus read operation back to the software model.

Message: Interrupt
Description: This message instructs the software model instance to call the interrupt service routine. No further Interrupt messages are issued until the interrupt service routine has completed, indicated by an IRet message.

Message: IRet
Description: This message re-enables the generation of Interrupt messages by the hardware model instance. This message is generated automatically after the interrupt service routine has terminated.

3.3.3 Software Model

Figure 3.3.3: Example Processor Class

This class implements a very simple SMI model of a processor. The test process provides a sequence of bus operations for the hardware model instance to perform. The test process calls methods provided by the software model instance that cause particular bus operations to be performed by the hardware model instance. The hardware model supports three bus operations which correspond to the methods, idle(), out(), in(). The idle() method generates a single inactive bus cycle. The out() method generates an I/O write bus operation, i.e. a data word is written to an address location via the processor bus. The in() method generates an I/O read bus operation, i.e. a data word read from an address location via the processor bus. Test process code written using these methods to perform I/O operations closely resembles code executable on the physical processor.

Internally, all three methods operate in a similar fashion. A message corresponding to the bus operation is constructed. The software model instance then waits for the hardware model instance to send a message requesting the next bus operation. The software model instance replies to this message with the message specifying the next bus operation. This procedure forces the test process to wait for the hardware simulation and thus remain in synchronization. At this point the idle() and out() methods return. The in() method, however, waits for the hardware model instance to send a message containing the data read by the bus operation. The in() method returns this data value once this message has been received.

The processor model also supports interrupt handling. When the hardware model instance signals an interrupt, it sends an interrupt message to the software model instance. On receiving this message, the software model instance saves the message corresponding to the bus operation that it was waiting to transmit. Then it calls the interrupt service routine supplied by the model user via a virtual method. This method should perform the bus operations required to disable the source of the interrupt. When the interrupt service routine ends, an interrupt return message is sent to the hardware model instance in place of a message specifying a bus operation. This message causes the hardware model instance to re-enable interrupt servicing, which was disabled during the execution of the interrupt service routine. The method interrupted by the receipt of the interrupt message is then ready to continue by restoring the message corresponding to the bus operation that it was waiting to transmit.

From the point of view of the test process, after posting all its models, the test process should periodically generate a processor bus operation by calling the appropriate method. At startup, the processor model will expect to receive a configuration message from the hardware model instance before any other message. After configuration, the processor model is ready to generate a bus operation. In this state, the processor model waits until a message is received from the hardware model instance. If the message requests the next bus operation, the corresponding message is sent. If the protocol ends there, the method returns. Otherwise, if the instruction expects a reply message, the test process will wait for the reply before the method returns. The test process will then run until the next time a bus operation method is called. At this point the processor model is ready to issue an new bus operation to the hardware model instance and the loop repeats.

It is important to note that a test process can support only one processor model instance using the example model presented in this section. The test process must not call SMI_Channel::wait() other than indirectly by calling the idle(), in() and out() methods supplied by the processor model instance.

Source: processor.h
processor.cc

Backward Up Forward
© Copyright 2000-2001 Adrian Lewis