)
: :
:
:
*
)
)
)
1
4
2
/0
3
C
5
*
)
)
)
)
)
)
*
)
*
)
)
)
. %
,'%
'
%
>
#
)
->
'
$
'!
#%
B
+
'&
>@
A
&
#- &
'(
!
)
'@A
$&
?
+
8
7 6 5
9
)
)
)
4
Fig 1. Architecture of a single-cycle mmMIPS processor
< 6 ;
C)
< )
D
=
)
)
*
3
E
:
!
$&
:
%
"!
:
'
'(
$%
#!
$%
Overall Structure of the C++ Model of a Processor
Red labels should be replaced by a proper type of a certain
signal.
//main function
main()
{
//…code not shown
sc_signal<TYPE>
bus_ram;
sc_signal<TYPE>
bus_rom;
sc_signal<TYPE>
bus_ram;
sc_signal<TYPE>
bus_rom;
//RAM module
SC_MODULE(RAM
)
{
//ROM module
SC_MODULE(ROM
)
{
sc_signal<TYPE>
bus_alu;
//ALU module
SC_MODULE(ALU)
{
//…code not shown
Main:
//…code not shown
/*
* INCLUDE FILES
*/
#include "alu.h"
#include "ram.h"
#include "rom.h"
//…code not shown
int sc_main(int argc, char *argv[])
{
char stbuf[256];
/*
* SIGNALS
*/
// Data signals
//…code not shown
sc_signal< TYPE> bus_ram;
sc_signal< TYPE> bus_rom;
sc_signal< TYPE> bus_alu;
//…code not shown
/* MODULES */
//…code not shown
ROM
imem("instruction_memory"); // Instruction memory
RAM
dmem("data_memory"); // Data memory
ALU
alu("alu");
//…code not shown
/*CONNECTIONS*/
// ALU
//…code not shown
alu.r(bus_alu);
//…code not shown
// Data memory
//…code not shown
dmem.a_write(bus_alu);
//…code not shown
// Instruction Memory;
//…code not shown
imem.d_read(bus_imem);
//…code not shown
/*
* TRACING
*/
sc_trace_file *tf;
tf = sc_create_vcd_trace_file("mips");
// Signals
sc_trace(tf, clk.signal(),
sc_trace(tf, bus_imem_1,
sc_trace(tf, bus_dmem_1,
sc_trace(tf, bus_alu_result,
sc_trace(tf, bus_alu_zero,
"clock");
"bus_imem_1");
"bus_dmem_1");
"bus_alu_result");
"bus_alu_zero");
for (int i = 0; i < REGSIZE; i++)
{
sprintf(stbuf, "registers.reg(%d)", i);
sc_trace(tf, registers.rfile[i], stbuf);
}
for (int i = 0; i < RAMSIZE; i++)
{
sprintf(stbuf, "memory.dmem(%d)", i);
sc_trace(tf, dmem.ramfile[i], stbuf);
}
for (int i = 0; i < ROMSIZE; i++)
{
sprintf(stbuf, "memory.imem(%d)", i);
sc_trace(tf, imem.romfile[i], stbuf);
}
/*
* SIMULATION
*/
unsigned int sim_time = 500;
if (argc == 2) sim_time = atoi(argv[1]);
sc_start(sim_time);
sc_close_vcd_trace_file(tf);
dmem.ram_dump("mips_ram.dump");
return 0;
}
process
process
process
Port, signal: data member of SC_MODULE class – specifies communication between
modules/proc.
(integer, boolean, bv ...)
Process: member function of SC_MODULE class – specifies combinational or sequential circuit
(SC_METHOD, SC_THREAD, SC_CTHREAD)
Signals
Ports
Module
Module and processes:
________________________________________________________________________
ALU Module:
Header file: Alu.h
#ifndef ALU_H_INCLUDED
#define ALU_H_INCLUDED
#include "mips.h"
SC_MODULE(ALU) {
sc_in< sc_bv<3> >
ctrl;
sc_in< sc_bv<DWORD> > a;
sc_in< sc_bv<DWORD> > b;
sc_out< sc_bv<DWORD> > r;
sc_out< sc_bv<1> >
z;
//(one in case result equal zero)
// Control input
// First operand input
// Second operand input
// Result
// Zero
void alu_thread();
// Constructor
SC_CTOR(ALU) {
SC_THREAD(alu_thread);
sensitive << ctrl << a << b;
}
// PROCESS REGISTRATION
// SENSITIVITY LIST
};
#endif
Body file: Alu.cpp
#include "alu.h"
void ALU::alu_thread()
{
sc_bv<DWORD> result;
//PROCESS DEFINITION
sc_bv<1>
sc_uint<DWORD>
sc_uint<DWORD>
sc_uint<3>
zero;
s;
t;
ctrl_t;
while (true) {
#ifdef VERBOSE
cerr << "ALU" << endl;
#endif
// Read the inputs
s = a.read();
t = b.read();
ctrl_t = ctrl.read();
// Calculate result using selected operation
switch (ctrl_t) {
case ALU_AND: // And
result = s & t;
break;
case ALU_OR: // Or
result = s | t;
break;
case ALU_ADD: // Add
result = s + t;
break;
case ALU_SUB: // Subtract
result = s - t;
break;
case ALU_SLT: // Set-on-less-than
if (s < t)
result = 1;
else
result = 0;
break;
/*
case ALU_MULTU: // Multiplication
result = s * t;
break;
*/
}
// Calculate the zero output
if (result == 0)
zero = 1;
else
zero = 0;
// Write results to output
r.write(result);
z.write(zero);
// Wait for next event
wait();
}
}
ALU Control Module:
Header file: aluctrl.h
#ifndef ALUCTRL_H_INCLUDED
#define ALUCTRL_H_INCLUDED
#include "mips.h"
SC_MODULE(ALUCTRL) {
sc_in< sc_bv<6> > functionCode; // Bit [0,5] of instruction
sc_in< sc_bv<2> > ALUop;
// ALU operation code
sc_out< sc_bv<3> > ALUctrl;
// Control output to ALU
void aluctrl_thread();
// Constructor
SC_CTOR(ALUCTRL) {
SC_THREAD(aluctrl_thread);
sensitive << functionCode << ALUop;
}
};
#endif
Body file: aluctrl.cpp
#include "aluctrl.h"
void ALUCTRL::aluctrl_thread()
{
sc_uint<3> aluCtrl;
sc_uint<2> aluop;
sc_uint<6> functioncode;
while (true) {
#ifdef VERBOSE
cerr << "ALUCTRL" << endl;
#endif
// Determine output
aluop = ALUop.read();
switch (aluop) {
case 0x0: // Add
aluCtrl = ALU_ADD;
break;
case 0x1: // Subtract
aluCtrl = ALU_SUB;
break;
case 0x2: // R-type instruction, look to functionCode
functioncode = functionCode.read();
functioncode = functioncode.range(5,0);
switch (functioncode) {
case FUNC_ADD: // Add
aluCtrl = ALU_ADD;
break;
case FUNC_SUB: // Subtract
aluCtrl = ALU_SUB;
break;
case FUNC_AND: // And
aluCtrl = ALU_AND;
break;
case FUNC_OR: // Or
aluCtrl = ALU_OR;
break;
case FUNC_SLT: // Set-on-less-than
aluCtrl = ALU_SLT;
break;
/*
case FUNC_MULTU: // Multiplication
aluCtrl = ALU_MULTU;
break;
*/
}
break;
}
// Set result on output
ALUctrl.write(aluCtrl);
// Wait for new event
wait();
}
}
Interconnections between modules:
Signals declaration:
//…code not shown
sc_signal< sc_bv<DWORD>
sc_signal< sc_bv<DWORD>
sc_signal< sc_bv<DWORD>
sc_signal< sc_bv<1>
//…code not shown
Connections:
//…code not shown
// ALU
alu.a(bus_registers_1);
alu.b(bus_mux2);
alu.r(bus_alu_result);
alu.z(bus_alu_zero);
alu.ctrl(bus_aluctrl);
// Data memory
dmem.a_read(bus_alu_result);
dmem.d_read(bus_dmem_1);
dmem.r(bus_ctrl_memread);
dmem.a_write(bus_alu_result);
dmem.d_write(bus_registers_2);
dmem.w(bus_ctrl_memwrite);
dmem.clk(clk);
// Instruction Memory
imem.a_read(bus_pc);
imem.d_read(bus_imem_1);
imem.clk(clk);
//…code not shown
> bus_imem_1;
> bus_dmem_1;
> bus_alu_result;
> bus_alu_zero;
ALU - removing, changing and adding instructions
alu.cpp modification:
// Calculate result using selected operation
switch (ctrl_t) {
//…code not shown
case ALU_SLT:
// Set-on-less-than
if (s < t)
result = 1;
else
result = 0;
break;
case ALU_MULTU:
result = s * t;
break;
//…code not shown
}
// Multiplication
aluctrl.cpp modification:
switch (aluop) {
//…code not shown
case FUNC_SLT: // Set-on-less-than
aluCtrl = ALU_SLT;
break;
case FUNC_MULTU: // Multiplication
aluCtrl = ALU_MULTU;
break;
//…code not shown
Removing, changing and adding ALU instructions is simple:
Files: alu.cpp and aluctrl.cpp has to be modified.
In alu.cpp and aluctrl.cpp the corresponding lists of arguments of the
switch/case statements have to be modified.
© Copyright 2025 Paperzz