问题描述
|
我正在模拟一个cpu,并且正在使用高级模拟工具进行此操作。 SystemC是用于这些目的的良好资源。我正在使用两个模块:
数据路径
记忆
cpu数据路径被建模为唯一的高级实体,但是以下代码肯定比任何其他解释都更好:
以下是datapath.hpp
SC_MODULE(DataPath) {
sc_in_clk clk;
sc_in<bool> rst;
///
/// Outgoing data from memory.
///
sc_in<w32> mem_data;
///
/// Memory read enable control signal.
///
sc_out<sc_logic> mem_ctr_memreadenable;
///
/// Memory write enable control signal.
///
sc_out<sc_logic> mem_ctr_memwriteenable;
///
/// Data to be written in memory.
///
sc_out<w32> mem_dataw; //w32 is sc_lv<32>
///
/// Address in mem to read and write.
///
sc_out<memaddr> mem_addr;
///
/// Program counter.
///
sc_signal<w32> pc;
///
/// State signal.
///
sc_signal<int> cu_state;
///
/// Other internal signals mapping registers\' value.
/// ...
// Defining process functions
///
/// Clock driven process to change state.
///
void state_process();
///
/// State driven process to apply control signals.
///
void control_process();
// Constructors
SC_CTOR(DataPath) {
// Defining first process
SC_CTHREAD(state_process,clk.neg());
reset_signal_is(this->rst,true);
// Defining second process
SC_METHOD(control_process);
sensitive << (this->cu_state) << (this->rst);
}
// Defining general functions
void reset_signals();
};
以下是datapath.cpp
void DataPath::state_process() {
// Useful variables
w32 ir_value; /* Placing here IR register value */
// Initialization phase
this->cu_state.write(StateFetch); /* StateFetch is a constant */
wait(); /* Wait next clock fall edge */
// Cycling
for (;;) {
// Checking state
switch (this->cu_state.read()) { // Basing on state,let\'s change the next one
case StateFetch: /* FETCH */
this->cu_state.write(StateDecode); /* Transition to DECODE */
break;
case StateDecode: /* DECODE */
// Doing decode
break;
case StateExecR: /* EXEC R */
// For every state,manage transition to the next state
break;
//...
//...
default: /* Possible not recognized state */
this->cu_state.write(StateFetch); /* Come back to fetch */
} /* switch */
// After doing,wait for the next clock fall edge
wait();
} /* for */
} /* function */
// State driven process for managing signal assignment
// This is a method process
void DataPath::control_process() {
// If reset signal is up then CU must be resetted
if (this->rst.read()) {
// Reset
this->reset_signals(); /* Initializing signals */
} else {
// No Reset
// Switching on state
switch (this->cu_state.read()) {
case StateFetch: /* FETCH */
// Managing memory address and instruction fetch to place in IR
this->mem_ctr_memreadenable.write(logic_sgm_1); /* Enabling memory to be read */
this->mem_ctr_memwriteenable.write(logic_sgm_0); /* disabling memory from being written */
std::cout << \"Entering fetch,memread=\" << this->mem_ctr_memreadenable.read() << \" memwrite=\" << this->mem_ctr_memreadenable.read() << std::endl;
// Here I read from memory and get the instruction with some code that you do not need to worry about because my problem occurs HERE ###
break;
case kCUStateDecode: /* DECODE */
// ...
break;
//...
//...
default: /* Unrecognized */
newpc = \"00000000000000000000000000000000\";
} /* state switch */
} /* rst if */
} /* function */
// Resetting signals
void DataPath::reset_signals() {
// Out signals
this->mem_ctr_memreadenable.write(logic_sgm_1);
this->mem_ctr_memwriteenable.write(logic_sgm_0);
}
如您所见,我们有一个时钟驱动的进程来处理cpu转换(改变状态),还有一个状态驱动的进程来为cpu设置信号。
我的问题是,当我到达###
时,我期望该指令被内存释放(您看不到指令,但它们是正确的,内存组件使用可以在hpp文件中看到的in和out信号连接到数据路径)。
记忆使我得到\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"
,因为mem_ctr_memreadenable
和mem_ctr_memwriteenable
都设置为to6 set。
编写内存模块以使其成为即时组件。它使用a7ѭ进行写入,其sensitive
在输入信号上定义(包括读取使能和写入使能)。当“ 4”信号为“ 6”时,存储组件为“ 9”。
为什么是\'0\'
?我重设信号并将该信号设置为\'1\'
。我不明白为什么我的读取使能信号一直保持6。
你能帮助我吗?
谢谢。
解决方法
我不是SystemC专家,但似乎与常见的VHDL问题类似,至少在经过一个delta周期后才更新信号:
this->mem_ctr_memreadenable.write(logic_sgm_1); /* Enabling memory to be read */
this->mem_ctr_memwriteenable.write(logic_sgm_0); /* Disabling memory from being written */
我的猜测:这两行与下一行之间没有时间:
std::cout << \"Entering fetch,memread=\" << this->mem_ctr_memreadenable.read() << \" memwrite=\" << this->mem_ctr_memreadenable.read() << std::endl;
因此内存尚未看到读取信号的变化。顺便说一句,附加到attached5ѭ的one17ѭ呼叫之一-应该都可以读取吗?
如果你:
wait(1,SC_NS);
在这两点之间,它是否有改善的作用?
,要与内存模块零时间同步,应使用
等待(SC_ZERO_TIME); //等待一个增量周期
不要在定时仿真中引入任意时间消耗。
这也迫使您将control_process升级到SC_THREAD