- Work on simulator

- Optimized wb_ddr_ctrl_wb_sc_fe and wb_ddr_ctrl_wb_dc[_fsm]
This commit is contained in:
2013-03-18 15:27:18 +01:00
parent be7f1337f2
commit 973513900d
15 changed files with 923 additions and 542 deletions

View File

@@ -56,17 +56,18 @@ XSTOPTS="-ifn $(PRJFILE) \
-ofn $(NGCFILE) \
-ofmt NGC \
-p $(PART) \
-opt_mode Speed \
-opt_level 1 \
-opt_mode Area \
-opt_level 2 \
-fsm_encoding auto \
-sd coregen/ \
-read_cores yes \
-rtlview no \
-iob auto \
-keep_hierarchy soft \
-register_balancing yes \
$(addprefix -uc ,$(XCF))"
NGDOPTS=-p $(PART) -aul -aut $(addprefix -uc ,$(UCF)) -sd coregen/
MAPOPTS=-p $(PART) -cm balanced -timing -ol high -logic_opt on -xe n
MAPOPTS=-p $(PART) -cm balanced -timing -ol high -logic_opt on -xe n -detail
PAROPTS=-ol high -xe n
BITGENOPTS=
TRACEOPTS=-v -u 10

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
##############################################################
#
# Xilinx Core Generator version 14.4
# Date: Sat Mar 02 09:54:41 2013
# Date: Mon Mar 18 11:03:09 2013
#
##############################################################
#
@@ -150,7 +150,7 @@ CSET overflow_flag_axi=false
CSET overflow_sense=Active_High
CSET overflow_sense_axi=Active_High
CSET performance_options=Standard_FIFO
CSET programmable_empty_type=No_Programmable_Empty_Threshold
CSET programmable_empty_type=Single_Programmable_Empty_Threshold_Constant
CSET programmable_empty_type_axis=No_Programmable_Empty_Threshold
CSET programmable_empty_type_rach=No_Programmable_Empty_Threshold
CSET programmable_empty_type_rdch=No_Programmable_Empty_Threshold
@@ -210,4 +210,4 @@ CSET wuser_width=1
MISC pkg_timestamp=2012-11-19T12:39:56Z
# END Extra information
GENERATE
# CRC: c2ee8dbb
# CRC: 3212baf8

View File

@@ -16,17 +16,15 @@ ReadPipe::~ReadPipe() {
void ReadPipe::readReq(unsigned long adr, unsigned long lines, unsigned long cols, unsigned long stride) {
assert(!req_ && !readInProgress_); // Previous request must be complete
assert(cols%2 == 0);
assert(stride%2 == 0);
adrReq_ = adr;
linesReq_ = lines;
colsReq_ = cols/2;
strideReq_ = stride/2;
colsReq_ = cols;
strideReq_ = stride;
req_ = true;
}
std::tuple<bool, uint32_t> ReadPipe::readFromPipe() {
std::tuple<bool, uint32_t> rval;
std::tuple<bool, uint64_t> ReadPipe::readFromPipe() {
std::tuple<bool, uint64_t> rval;
if(!readInProgress_) {
assert(req_);
memPos_ = adrReq_;
@@ -35,29 +33,22 @@ std::tuple<bool, uint32_t> ReadPipe::readFromPipe() {
lineBase_ = adrReq_;
req_ = false;
readInProgress_ = true;
readHigh_ = false;
}
if(readHigh_) {
rval = std::tuple<bool, uint32_t>(true, mem_.read(memPos_)>>32);
readHigh_ = false;
if(colCtr_ == 0) {
if(lineCtr_ == 0) {
readInProgress_ = false;
cout << "ReadPipe: " << colsReq_ << "x" << linesReq_ << "@" << adrReq_ << " complete" << endl;
} else {
lineBase_ += strideReq_;
memPos_ = lineBase_;
colCtr_ = colsReq_-1;
--lineCtr_;
}
rval = std::tuple<bool, uint64_t>(true, mem_.read(memPos_));
if(colCtr_ == 0) {
if(lineCtr_ == 0) {
readInProgress_ = false;
cout << "ReadPipe: " << colsReq_ << "x" << linesReq_ << "@" << adrReq_ << " complete" << endl;
} else {
++memPos_;
--colCtr_;
}
lineBase_ += strideReq_;
memPos_ = lineBase_;
colCtr_ = colsReq_-1;
--lineCtr_;
}
} else {
rval = std::tuple<bool, uint32_t>(true, mem_.read(memPos_));
readHigh_ = true;
++memPos_;
--colCtr_;
}
return rval;

View File

@@ -14,7 +14,11 @@ public:
void readReq(unsigned long adr, unsigned long lines, unsigned long cols, unsigned long stride);
std::tuple<bool, uint32_t> readFromPipe();
std::tuple<bool, uint64_t> readFromPipe();
bool active() const {
return readInProgress_ || req_;
}
private:
Memory& mem_;
@@ -22,7 +26,7 @@ private:
unsigned long adrReq_, linesReq_, colsReq_, strideReq_;
bool req_;
bool readInProgress_, readHigh_;
bool readInProgress_;
unsigned long memPos_, lineCtr_, colCtr_, lineBase_;
};

View File

@@ -1,108 +1,90 @@
#include <iostream>
#include <ios>
#include <iomanip>
#include "Memory.hh"
#include "Simulator.hh"
Simulator::Simulator(Memory& mem) : mem_(mem), rp1_(mem), rp2_(mem), wp_(mem) {
using std::cout;
using std::endl;
using std::hex;
using std::dec;
using std::setw;
using std::setfill;
Simulator::Simulator(Memory& mem) : mem_(mem), rp1_(mem), rp2_(mem), wp_(mem),
pc_(0), lastInstrPipeC_(false), cycle_(0) {
}
Simulator::~Simulator() {
}
enum states {
S_INIT,
S_FILL,
S_BLITINIT,
S_BLIT,
S_DONE
enum itypes {
T_PIPECTRL,
T_IMM,
T_OUT,
T_IN,
T_ANDI,
T_CMPI,
T_MOV,
T_DONE,
T_BREAK
};
void Simulator::step() {
static unsigned x = 0, y = 0;
static states state = S_INIT;
enum imodes {
M_Q,
M_D,
M_W,
M_2D,
M_4W
};
uint32_t t1val, t2val, wval;
// Values 0..7 are valid
typedef unsigned char reg_sel;
switch(state) {
case S_INIT:
wp_.writeReq(0, 480, 320, 320);
state = S_FILL;
case S_FILL:
if(y == 0 || y == 479)
wval = 0x0fff0ffful;
else if(x==0)
wval = 0x00000ffful;
else if(x==319)
wval = 0x0fff0000ul;
else if(x < 106)
wval = 0x0f000f00ul;
else if(x < 212)
wval = 0x00f000f0ul;
else
wval = 0x000f000ful;
if(x == 319) {
x = 0;
++y;
if(y == 480)
state = S_BLITINIT;
} else
++x;
wp_.writeToPipe(wval);
break;
case S_BLITINIT:
rp1_.readReq(0x20000, 200, 100, 100);
rp2_.readReq(22455, 200, 100, 320);
wp_.writeReq(22455, 200, 100, 320);
x = 0;
y = 0;
state = S_BLIT;
case S_BLIT:
t1val = std::get<1>(rp1_.readFromPipe());
t2val = std::get<1>(rp2_.readFromPipe());
wval = t2val;
if((t1val&0x0fff) != 0x0fff) {
wval &= 0xffff0000;
wval |= t1val&0xffff;
}
if((t1val&0x0fff0000) != 0x0fff0000) {
wval &= 0x0000ffff;
wval |= t1val&0xffff0000;
}
wp_.writeToPipe(wval);
if(x == 99) {
x = 0;
++y;
if(y == 200)
state = S_DONE;
} else
++x;
break;
case S_DONE:
break;
}
}
#define INPIPE0 0
#define INPIPE1 1
#define OUTPIPE 7
/*
typedef struct {
itypes itype;
conds cond;
imodes imode;
reg_sel src1, src2, dst;
unsigned subreg;
uint16_t imm;
unsigned long pstart, plines, pcols, pstride;
} instr_t;
static const instr_t irom[] = {
/*
Fill:
# red
@outpipe 161, 478, 106, 320
IMM.4W r0, 0x0f00
OUT.Q r0
# green
@outpipe 214, 478, 104, 320
IMM.4W r0, 0x00f0
OUT.Q r0
# blue
@outpipe 266, 478, 106, 320
IMM.4W r0, 0x000f
OUT.Q r0
# top border
@outpipe 0, 1, 320, 320
IMM.4W r0, 0x0fff
OUT.Q r0
# bottom border
@outpipe 76640, 1, 320, 320
IMM.4W r0, 0x0fff
OUT.Q r0
# left border 2nd row
@outpipe 160, 1, 2, 2
IMM.4W r0, 0x0f00
IMM.W r0.0 0x0fff
OUT.Q r0
# l/r borders
@outpipe 319, 478, 4, 320
IMM.4W r0, 0x000f
IMM.W r0.3, 0x0fff
@@ -110,11 +92,52 @@ OUT.Q r0
IMM.4W r0, 0x0f00
IMM.W r0.0, 0x0fff
OUT.Q r0
# right border 479th row
@outpipe 76639, 1, 2, 2
IMM.4W r0, 0x000f
IMM.W r0.3, 0x0fff
OUT.Q r0
*/
{T_PIPECTRL, C_ALWAYS, M_Q, 0, 0, OUTPIPE, 0, 0, 161, 478, 53, 160},
{T_IMM, C_ALWAYS, M_4W, 0, 0, 0, 0, 0x0f00, 0, 0, 0, 0},
{T_OUT, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_DONE, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_PIPECTRL, C_ALWAYS, M_Q, 0, 0, OUTPIPE, 0, 0, 214, 478, 52, 160},
{T_IMM, C_ALWAYS, M_4W, 0, 0, 0, 0, 0x00f0, 0, 0, 0, 0},
{T_OUT, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_DONE, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_PIPECTRL, C_ALWAYS, M_Q, 0, 0, OUTPIPE, 0, 0, 266, 478, 53, 160},
{T_IMM, C_ALWAYS, M_4W, 0, 0, 0, 0, 0x000f, 0, 0, 0, 0},
{T_OUT, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_DONE, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_PIPECTRL, C_ALWAYS, M_Q, 0, 0, OUTPIPE, 0, 0, 0, 1, 160, 160},
{T_IMM, C_ALWAYS, M_4W, 0, 0, 0, 0, 0x0fff, 0, 0, 0, 0},
{T_OUT, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_DONE, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_PIPECTRL, C_ALWAYS, M_Q, 0, 0, OUTPIPE, 0, 0, 76640, 1, 160, 160},
{T_IMM, C_ALWAYS, M_4W, 0, 0, 0, 0, 0x0fff, 0, 0, 0, 0},
{T_OUT, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_DONE, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_PIPECTRL, C_ALWAYS, M_Q, 0, 0, OUTPIPE, 0, 0, 160, 1, 1, 1},
{T_IMM, C_ALWAYS, M_4W, 0, 0, 0, 0, 0x0f00, 0, 0, 0, 0},
{T_IMM, C_ALWAYS, M_W, 0, 0, 0, 0, 0x0fff, 0, 0, 0, 0},
{T_OUT, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_DONE, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_PIPECTRL, C_ALWAYS, M_Q, 0, 0, OUTPIPE, 0, 0, 319, 477, 2, 160},
{T_IMM, C_ALWAYS, M_4W, 0, 0, 0, 0, 0x000f, 0, 0, 0, 0},
{T_IMM, C_ALWAYS, M_W, 0, 0, 0, 3, 0x0fff, 0, 0, 0, 0},
{T_OUT, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_IMM, C_ALWAYS, M_4W, 0, 0, 0, 0, 0x0f00, 0, 0, 0, 0},
{T_IMM, C_ALWAYS, M_W, 0, 0, 0, 0, 0x0fff, 0, 0, 0, 0},
{T_OUT, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_DONE, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_PIPECTRL, C_ALWAYS, M_Q, 0, 0, OUTPIPE, 0, 0, 76639, 1, 1, 1},
{T_IMM, C_ALWAYS, M_4W, 0, 0, 0, 0, 0x000f, 0, 0, 0, 0},
{T_IMM, C_ALWAYS, M_W, 0, 0, 0, 3, 0x0fff, 0, 0, 0, 0},
{T_OUT, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{T_DONE, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0},
/*
Mask blit:
@inpipe0 0x20000, 200, 100, 100
@inpipe1 22455, 200, 100, 320
@@ -126,3 +149,329 @@ CMP.4W r2, 0x0fff // compare high and low word of r2 with 0x0fff and set high an
EQ.MOV.4W r1, r0 // conditional execute a mov of high/low word of r1 to r0 if high/low eq flag is set
OUT.Q r0 // write a qword from r0 to outpipe
*/
// 38
{T_PIPECTRL, C_ALWAYS, M_Q, 0, 0, INPIPE0, 0, 0, 0x20000, 200, 50, 50}, // 38
{T_PIPECTRL, C_ALWAYS, M_Q, 0, 0, INPIPE1, 0, 0, 22455, 200, 50, 160}, // 39
{T_PIPECTRL, C_ALWAYS, M_Q, 0, 0, OUTPIPE, 0, 0, 22455, 200, 50, 160}, // 40
{T_IN, C_ALWAYS, M_Q, INPIPE0, 0, 0, 0, 0, 0, 0, 0, 0}, // 41
{T_IN, C_ALWAYS, M_Q, INPIPE1, 0, 1, 0, 0, 0, 0, 0, 0}, // 42
{T_ANDI, C_ALWAYS, M_4W, 0, 0, 2, 0, 0x0fff, 0, 0, 0, 0}, // 43
{T_CMPI, C_ALWAYS, M_4W, 2, 0, 0, 0, 0x0fff, 0, 0, 0, 0}, // 44
{T_MOV, C_EQUAL, M_4W, 1, 0, 0, 0, 0, 0, 0, 0, 0}, // 45
{T_OUT, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // 46
{T_DONE, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // 47
// STOP simulator
{T_BREAK, C_ALWAYS, M_Q, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
void Simulator::step() {
instr_t cur_inst = irom[pc_++];
if(cur_inst.itype != T_PIPECTRL) {
if(lastInstrPipeC_) {
startPC_ = pc_-1;
}
lastInstrPipeC_ = false;
}
switch(cur_inst.itype) {
case T_PIPECTRL:
assert(cur_inst.cond == C_ALWAYS);
lastInstrPipeC_ = true;
switch(cur_inst.dst) {
case INPIPE0:
rp1_.readReq(cur_inst.pstart, cur_inst.plines, cur_inst.pcols, cur_inst.pstride);
break;
case INPIPE1:
rp2_.readReq(cur_inst.pstart, cur_inst.plines, cur_inst.pcols, cur_inst.pstride);
break;
case OUTPIPE:
wp_.writeReq(cur_inst.pstart, cur_inst.plines, cur_inst.pcols, cur_inst.pstride);
break;
default:
assert(false);
}
break;
case T_DONE:
assert(cur_inst.cond == C_ALWAYS);
if(rp1_.active() || rp2_.active() || wp_.active())
pc_ = startPC_;
break;
case T_CMPI:
switch(cur_inst.imode) {
case M_Q:
if(check_cond(cur_inst.cond, 0)) {
flags_[0] = cmp(regs_[cur_inst.src1].qw, static_cast<uint64_t>(cur_inst.imm));
}
break;
case M_D:
if(check_cond(cur_inst.cond, cur_inst.subreg)) {
flags_[cur_inst.subreg] = cmp(regs_[cur_inst.src1].dw[cur_inst.subreg],
static_cast<uint32_t>(cur_inst.imm));
}
break;
case M_W:
if(check_cond(cur_inst.cond, cur_inst.subreg)) {
flags_[cur_inst.subreg] = cmp(regs_[cur_inst.src1].w[cur_inst.subreg],
cur_inst.imm);
}
break;
case M_2D:
for(int i = 0;i < 2; ++i) {
if(check_cond(cur_inst.cond, i*2)) {
flags_[i*2] = cmp(regs_[cur_inst.src1].dw[i],
static_cast<uint32_t>(cur_inst.imm));
}
}
break;
case M_4W:
for(int i = 0;i < 4; ++i) {
if(check_cond(cur_inst.cond, i)) {
flags_[i] = cmp(regs_[cur_inst.src1].w[i], cur_inst.imm);
}
}
break;
}
break;
case T_IMM:
switch(cur_inst.imode) {
case M_Q:
if(check_cond(cur_inst.cond, 0)) {
regs_[cur_inst.dst].qw = cur_inst.imm;
}
break;
case M_D:
if(check_cond(cur_inst.cond, cur_inst.subreg)) {
regs_[cur_inst.dst].dw[cur_inst.subreg] = cur_inst.imm;
}
break;
case M_W:
if(check_cond(cur_inst.cond, cur_inst.subreg)) {
regs_[cur_inst.dst].w[cur_inst.subreg] = cur_inst.imm;
}
break;
case M_2D:
for(int i = 0;i < 2; ++i) {
if(check_cond(cur_inst.cond, i*2)) {
regs_[cur_inst.dst].dw[i] = cur_inst.imm;
}
}
break;
case M_4W:
for(int i = 0;i < 4; ++i) {
if(check_cond(cur_inst.cond, i)) {
regs_[cur_inst.dst].w[i] = cur_inst.imm;
}
}
break;
}
break;
case T_ANDI:
switch(cur_inst.imode) {
case M_Q:
if(check_cond(cur_inst.cond, 0)) {
regs_[cur_inst.dst].qw = regs_[cur_inst.src1].qw & cur_inst.imm;
}
break;
case M_D:
if(check_cond(cur_inst.cond, cur_inst.subreg*2)) {
regs_[cur_inst.dst].dw[cur_inst.subreg] = regs_[cur_inst.src1].dw[cur_inst.subreg] & cur_inst.imm;
}
break;
case M_W:
if(check_cond(cur_inst.cond, cur_inst.subreg)) {
regs_[cur_inst.dst].w[cur_inst.subreg] = regs_[cur_inst.src1].w[cur_inst.subreg] & cur_inst.imm;
}
break;
case M_2D:
for(int i = 0;i < 2; ++i) {
if(check_cond(cur_inst.cond, i*2)) {
regs_[cur_inst.dst].dw[i] = regs_[cur_inst.src1].dw[i] & cur_inst.imm;
}
}
break;
case M_4W:
for(int i = 0;i < 4; ++i) {
if(check_cond(cur_inst.cond, i)) {
regs_[cur_inst.dst].w[i] = regs_[cur_inst.src1].w[i] & cur_inst.imm;
}
}
break;
}
break;
case T_MOV:
switch(cur_inst.imode) {
case M_Q:
if(check_cond(cur_inst.cond, 0)) {
regs_[cur_inst.dst].qw = regs_[cur_inst.src1].qw;
}
break;
case M_D:
if(check_cond(cur_inst.cond, cur_inst.subreg)) {
regs_[cur_inst.dst].dw[cur_inst.subreg] = regs_[cur_inst.src1].dw[cur_inst.subreg];
}
break;
case M_W:
if(check_cond(cur_inst.cond, cur_inst.subreg)) {
regs_[cur_inst.dst].w[cur_inst.subreg] = regs_[cur_inst.src1].w[cur_inst.subreg];
}
break;
case M_2D:
for(int i = 0;i < 2; ++i) {
if(check_cond(cur_inst.cond, i*2)) {
regs_[cur_inst.dst].dw[i] = regs_[cur_inst.src1].dw[i];
}
}
break;
case M_4W:
for(int i = 0;i < 4; ++i) {
if(check_cond(cur_inst.cond, i)) {
regs_[cur_inst.dst].w[i] = regs_[cur_inst.src1].w[i] ;
}
}
break;
}
break;
case T_OUT:
assert(cur_inst.imode == M_Q); // byte write enable to mem NYI
if(check_cond(cur_inst.cond, 0)) {
wp_.writeToPipe(regs_[cur_inst.src1].qw);
}
break;
case T_IN:
assert(cur_inst.imode == M_Q);
assert(cur_inst.src1 == INPIPE0 || cur_inst.src1 == INPIPE1);
if(check_cond(cur_inst.cond, 0)) {
if(cur_inst.src1 == INPIPE0) {
auto read = rp1_.readFromPipe();
if(std::get<0>(read))
regs_[cur_inst.dst].qw = std::get<1>(read);
else
--pc_;
} else {
auto read = rp2_.readFromPipe();
if(std::get<0>(read))
regs_[cur_inst.dst].qw = std::get<1>(read);
else
--pc_;
}
}
break;
case T_BREAK:
--pc_;
}
// print_state();
++cycle_;
}
bool Simulator::check_cond(conds cond, unsigned flag_set) const {
if(cond == C_ALWAYS)
return true;
if(cond == C_NEVER)
return false;
if(cond == C_EQUAL)
return flags_[flag_set].z;
if(cond == C_NOTEQUAL)
return !flags_[flag_set].z;
assert(false);
}
template<typename T> Simulator::flags_t Simulator::cmp(T a, T b) {
flags_t ret;
ret.z = ((a-b)==0);
return ret;
}
void Simulator::print_state() const {
cout << "Cycle " << cycle_ << " PC: " << pc_ << " LoopPoint: " << startPC_ << endl;
cout << "Registers:" << endl;
for(int i = 0;i < 8;++i) {
cout << "\tr" << i << ":\t" << setfill('0') << setw(16) << hex << regs_[i].qw << setfill(' ') << dec << endl;
}
cout << "Flags:" << endl;
for(int i = 0;i < 4;++i) {
cout << "\tf" << i <<":\t" << (flags_[i].z?'Z':' ') << endl;
}
cout << endl;
}
// static unsigned x = 0, y = 0;
// static states state = S_INIT;
// uint32_t t1val, t2val, wval;
// switch(state) {
// case S_INIT:
// wp_.writeReq(0, 480, 320, 320);
// state = S_FILL;
// case S_FILL:
// if(y == 0 || y == 479)
// wval = 0x0fff0ffful;
// else if(x==0)
// wval = 0x00000ffful;
// else if(x==319)
// wval = 0x0fff0000ul;
// else if(x < 106)
// wval = 0x0f000f00ul;
// else if(x < 212)
// wval = 0x00f000f0ul;
// else
// wval = 0x000f000ful;
// if(x == 319) {
// x = 0;
// ++y;
// if(y == 480)
// state = S_BLITINIT;
// } else
// ++x;
// wp_.writeToPipe(wval);
// break;
// case S_BLITINIT:
// rp1_.readReq(0x20000, 200, 100, 100);
// rp2_.readReq(22455, 200, 100, 320);
// wp_.writeReq(22455, 200, 100, 320);
// x = 0;
// y = 0;
// state = S_BLIT;
// case S_BLIT:
// t1val = std::get<1>(rp1_.readFromPipe());
// t2val = std::get<1>(rp2_.readFromPipe());
// wval = t2val;
// if((t1val&0x0fff) != 0x0fff) {
// wval &= 0xffff0000;
// wval |= t1val&0xffff;
// }
// if((t1val&0x0fff0000) != 0x0fff0000) {
// wval &= 0x0000ffff;
// wval |= t1val&0xffff0000;
// }
// wp_.writeToPipe(wval);
// if(x == 99) {
// x = 0;
// ++y;
// if(y == 200)
// state = S_DONE;
// } else
// ++x;
// break;
// case S_DONE:
// break;
// }
// }

View File

@@ -8,6 +8,13 @@
class Memory;
enum conds {
C_ALWAYS,
C_NEVER,
C_EQUAL,
C_NOTEQUAL
};
class Simulator {
public:
Simulator(Memory& mem);
@@ -16,9 +23,33 @@ public:
void step();
private:
void print_state() const;
bool check_cond(conds cond, unsigned flag_set) const;
Memory& mem_;
ReadPipe rp1_, rp2_;
WritePipe wp_;
unsigned long pc_, startPC_;
bool lastInstrPipeC_;
typedef union {
uint64_t qw;
uint32_t dw[2];
uint16_t w[4];
} reg_t;
reg_t regs_[8];
typedef struct {
bool z;
} flags_t;
template<typename T> flags_t cmp(T a, T b);
flags_t flags_[4];
unsigned long cycle_;
};
#endif

View File

@@ -16,16 +16,14 @@ WritePipe::~WritePipe() {
void WritePipe::writeReq(unsigned long adr, unsigned long lines, unsigned long cols, unsigned long stride) {
assert(!req_ && !writeInProgress_); // Previous request must be complete
assert(strideReq_%2 == 0);
assert(colsReq_%2 == 0);
adrReq_ = adr;
linesReq_ = lines;
colsReq_ = cols/2;
strideReq_ = stride/2;
colsReq_ = cols;
strideReq_ = stride;
req_ = true;
}
bool WritePipe::writeToPipe(uint32_t data) {
bool WritePipe::writeToPipe(uint64_t data) {
if(!writeInProgress_) {
assert(req_);
memPos_ = adrReq_;
@@ -34,29 +32,22 @@ bool WritePipe::writeToPipe(uint32_t data) {
lineCtr_ = linesReq_;
req_ = false;
writeInProgress_ = true;
writeHigh_ = false;
}
if(writeHigh_) {
mem_.write(memPos_, static_cast<uint64_t>(data)<<32 | lowDataBuf_);
writeHigh_ = false;
if(colCtr_ == 0) {
--lineCtr_;
if(lineCtr_ == 0) {
writeInProgress_ = false;
cout << "WritePipe: " << colsReq_ << "x" << linesReq_ << "@" << adrReq_ << " complete" << endl;
}
lineBase_ += strideReq_;
memPos_ = lineBase_;
colCtr_ = colsReq_-1;
} else {
++memPos_;
--colCtr_;
mem_.write(memPos_, data);
if(colCtr_ == 0) {
--lineCtr_;
if(lineCtr_ == 0) {
writeInProgress_ = false;
cout << "WritePipe: " << colsReq_ << "x" << linesReq_ << "@" << adrReq_ << " complete" << endl;
}
lineBase_ += strideReq_;
memPos_ = lineBase_;
colCtr_ = colsReq_-1;
} else {
lowDataBuf_ = data;
writeHigh_ = true;
++memPos_;
--colCtr_;
}
return true;
}

View File

@@ -14,7 +14,11 @@ public:
void writeReq(unsigned long adr, unsigned long lines, unsigned long cols, unsigned long stride);
bool writeToPipe(uint32_t data);
bool writeToPipe(uint64_t data);
bool active() const {
return writeInProgress_ || req_;
}
private:
Memory& mem_;
@@ -22,9 +26,8 @@ private:
unsigned long adrReq_, linesReq_, colsReq_, strideReq_;
bool req_;
bool writeInProgress_, writeHigh_;
bool writeInProgress_;
unsigned long memPos_, lineCtr_, colCtr_, lineBase_;
uint32_t lowDataBuf_;
};
#endif

View File

@@ -97,7 +97,8 @@ component wb_ddr_ctrl_wb_to_ddr IS
rd_en : IN STD_LOGIC;
dout : OUT STD_LOGIC_VECTOR(95 DOWNTO 0);
full : OUT STD_LOGIC;
empty : OUT STD_LOGIC
empty : OUT STD_LOGIC;
prog_empty : out std_logic
);
END component;
component wb_ddr_ctrl_wb_sc is
@@ -163,13 +164,14 @@ component wb_ddr_ctrl_wb_dc is
fifo_to_sys_write : out std_ulogic;
fifo_from_sys_read : out std_ulogic;
fifo_to_sys_full : in std_ulogic;
fifo_from_sys_empty : in std_ulogic
fifo_from_sys_empty : in std_ulogic;
fifo_from_sys_almost_empty : in std_logic
);
end component;
-- FIFO control signals
signal s2d_fifo_rd, s2d_fifo_wr, d2s_fifo_rd, d2s_fifo_wr : std_ulogic;
signal s2d_fifo_empty, s2d_fifo_full, d2s_fifo_empty, d2s_fifo_full : std_ulogic;
signal s2d_fifo_empty, s2d_fifo_almost_empty, s2d_fifo_full, d2s_fifo_empty, d2s_fifo_full : std_ulogic;
-- FIFO data signals
signal s2d_fifo_din : std_logic_vector(95 downto 0);
@@ -219,6 +221,7 @@ s2d_fifo : wb_ddr_ctrl_wb_to_ddr
rd_en => s2d_fifo_rd,
full => s2d_fifo_full,
empty => s2d_fifo_empty,
prog_empty => s2d_fifo_almost_empty,
din => s2d_fifo_din,
@@ -271,7 +274,8 @@ ddr_cd_inst : wb_ddr_ctrl_wb_dc
fifo_to_sys_write => d2s_fifo_wr,
fifo_from_sys_read => s2d_fifo_rd,
fifo_to_sys_full => d2s_fifo_full,
fifo_from_sys_empty => s2d_fifo_empty
fifo_from_sys_empty => s2d_fifo_empty,
fifo_from_sys_almost_empty => s2d_fifo_almost_empty
);
end Behavioral;

View File

@@ -62,7 +62,8 @@ entity wb_ddr_ctrl_wb_dc is
fifo_to_sys_write : out std_ulogic;
fifo_from_sys_read : out std_ulogic;
fifo_to_sys_full : in std_ulogic;
fifo_from_sys_empty : in std_ulogic
fifo_from_sys_empty : in std_ulogic;
fifo_from_sys_almost_empty : in std_logic
);
end wb_ddr_ctrl_wb_dc;
@@ -80,6 +81,7 @@ architecture Behavioral of wb_ddr_ctrl_wb_dc is
ctrl_init_done : in std_logic;
ctrl_ar_done : in std_logic;
fifo_from_sys_empty : in std_ulogic;
fifo_from_sys_almost_empty : in std_logic;
we : in std_ulogic;
row_addr : in std_ulogic_vector(12 downto 0);
ddr_address_en : out std_ulogic;
@@ -123,6 +125,7 @@ wb_ddr_ctrl_wb_dc_fsm_inst: wb_ddr_ctrl_wb_dc_fsm
ctrl_init_done => ctrl_init_done,
ctrl_ar_done => ctrl_ar_done,
fifo_from_sys_empty => fifo_from_sys_empty,
fifo_from_sys_almost_empty => fifo_from_sys_almost_empty,
we => we,
row_addr => adr(20 downto 8),
ddr_address_en => ddr_address_en,

View File

@@ -46,6 +46,7 @@ entity wb_ddr_ctrl_wb_dc_fsm is
ctrl_init_done : in std_logic;
ctrl_ar_done : in std_logic;
fifo_from_sys_empty : in std_ulogic;
fifo_from_sys_almost_empty : in std_logic;
we : in std_ulogic;
row_addr : in std_ulogic_vector(12 downto 0);
@@ -85,9 +86,9 @@ begin
is_fifo_from_sys_valid : process(ddr2_clk0)
is_fifo_from_sys_valid : process(ddr2_clk180)
begin
if rising_edge(ddr2_clk0) then
if rising_edge(ddr2_clk180) then
if fifo_from_sys_read_int = '1' then
fifo_from_sys_valid <= not fifo_from_sys_empty;
end if;
@@ -116,7 +117,7 @@ ctrl_fsm_state : process(ddr2_clk180)
if ctrl_auto_ref_req = '1' then -- DDR controller requests refresh
ctrl_state <= S_REFRESH;
fifo_pending <= fifo_from_sys_valid;
elsif fifo_from_sys_valid = '1' then -- A request from the system is pending
elsif fifo_from_sys_almost_empty = '0' then -- A request from the system is pending
ctrl_state <= S_REQUEST_INIT;
end if; -- else do nothing
when S_REFRESH =>
@@ -140,7 +141,7 @@ ctrl_fsm_state : process(ddr2_clk180)
when S_WRITE2 =>
fifo_pending <= '-';
if fifo_from_sys_valid = '0' or row_addr /= burst_start_adr or
we = '0' or ctrl_auto_ref_req = '1' then
we = '0' then -- or ctrl_auto_ref_req = '1' then
-- next request incompatible with burst type, or auto refresh requested
fifo_pending <= fifo_from_sys_valid;
ctrl_state <= S_WRITE_END1;
@@ -174,7 +175,7 @@ ctrl_fsm_state : process(ddr2_clk180)
when S_READ4 =>
fifo_pending <= '-';
if fifo_from_sys_valid = '0' or row_addr /= burst_start_adr or
we = '1' or ctrl_auto_ref_req = '1' then
we = '1' then -- or ctrl_auto_ref_req = '1' then
-- next request incompatible with burst type, or auto refresh requested
fifo_pending <= fifo_from_sys_valid;
ctrl_state <= S_READ_END1;
@@ -211,7 +212,8 @@ ctrl_fsm_state : process(ddr2_clk180)
ctrl_fsm_out : process(ctrl_state, ddr2_reset, we, ctrl_cmd_ack, fifo_from_sys_valid,
row_addr, burst_start_adr, ctrl_auto_ref_req, fifo_pending)
row_addr, burst_start_adr, ctrl_auto_ref_req, fifo_pending,
fifo_from_sys_almost_empty)
begin
ddr_dmask_rst <= '0'; -- dmask register reset
ddr_dmask_en <= '0'; -- dmask register enable
@@ -227,7 +229,8 @@ ctrl_fsm_out : process(ctrl_state, ddr2_reset, we, ctrl_cmd_ack, fifo_from_sys_v
when S_INITIALIZE =>
ctrl_command_register_d <= ctrl_command_initialize;
when S_IDLE =>
if ctrl_auto_ref_req = '0' and fifo_pending = '0' then
if ctrl_auto_ref_req = '0' and fifo_pending = '0' and
fifo_from_sys_almost_empty = '0' then
fifo_from_sys_read_int <= '1';
end if;
when S_REQUEST_INIT =>
@@ -255,7 +258,7 @@ ctrl_fsm_out : process(ctrl_state, ddr2_reset, we, ctrl_cmd_ack, fifo_from_sys_v
ddr_dout_en <= '1';
ddr_dout_high <= '0';
if fifo_from_sys_valid = '0' or row_addr /= burst_start_adr or
we = '0' or ctrl_auto_ref_req = '1' then
we = '0' then -- or ctrl_auto_ref_req = '1' then
-- next request incompatible with burst type, or auto refresh requested
else
@@ -288,7 +291,7 @@ ctrl_fsm_out : process(ctrl_state, ddr2_reset, we, ctrl_cmd_ack, fifo_from_sys_v
when S_READ4 =>
ddr_address_en <= '1';
if fifo_from_sys_valid = '0' or row_addr /= burst_start_adr or
we = '1' or ctrl_auto_ref_req = '1' then
we = '1' then -- or ctrl_auto_ref_req = '1' then
-- next request incompatible with burst type, or auto refresh requested
ctrl_burst_done_d <= '1';
else

View File

@@ -201,8 +201,8 @@ begin
cache_wr_addr <= adr_index & adr_tag_eq_num & adr_offset when cache_from_mem = '0' else
adr_index & eject_num & mem_offset;
cache_wr_data <= wbs_i.dat_i & wbs_i.dat_i when cache_write = '1' else
mem_dat_i when cache_from_mem = '1' else
(others => dontcare);
mem_dat_i;-- when cache_from_mem = '1' else
--(others => dontcare);
cache_bwe <= "0000" & wbs_i.sel_i when cache_write = '1' and wbs_i.adr_i(2) = '0' else
wbs_i.sel_i & "0000" when cache_write = '1' and wbs_i.adr_i(2) = '1' else
"11111111" when cache_from_mem = '1' and mem_ack = '1' else

View File

@@ -6,7 +6,7 @@
-- Author : <Matthias@MATTHIAS-PC>
-- Company :
-- Created : 2013-03-02
-- Last update: 2013-03-09
-- Last update: 2013-03-18
-- Platform :
-- Standard : VHDL'87
-------------------------------------------------------------------------------
@@ -45,7 +45,7 @@ architecture testbench of toplevel_tb is
vga_vsync, vga_hsync : OUT std_ulogic;
dataflash_mosi, dataflash_sck, dataflash_ss, dataflash_wp, dataflash_rst : OUT std_ulogic;
dataflash_miso : IN std_ulogic;
led : OUT std_ulogic_vector(7 downto 0);
-- led : OUT std_ulogic_vector(7 downto 0);
ddr2_dq : inout std_logic_vector(15 downto 0);
ddr2_a : out std_logic_vector(12 downto 0);
ddr2_ba : out std_logic_vector(1 downto 0);
@@ -136,7 +136,7 @@ begin -- testbench
dataflash_wp => dataflash_wp,
dataflash_rst => dataflash_rst,
dataflash_miso => dataflash_miso,
led => led,
-- led => led,
ddr2_dq => ddr2_dq,
ddr2_a => ddr2_a,
ddr2_ba => ddr2_ba,

View File

@@ -22,7 +22,7 @@
</top_modules>
</db_ref>
</db_ref_list>
<WVObjectSize size="45" />
<WVObjectSize size="44" />
<wvobject fp_name="/toplevel_tb/DUT/clkin_50mhz" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">clkin_50mhz</obj_property>
<obj_property name="ObjectShortName">clkin_50mhz</obj_property>
@@ -82,10 +82,6 @@
<obj_property name="ElementShortName">dataflash_miso</obj_property>
<obj_property name="ObjectShortName">dataflash_miso</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/led" type="array" db_ref_id="1">
<obj_property name="ElementShortName">led[7:0]</obj_property>
<obj_property name="ObjectShortName">led[7:0]</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/ddr2_dq" type="array" db_ref_id="1">
<obj_property name="ElementShortName">ddr2_dq[15:0]</obj_property>
<obj_property name="ObjectShortName">ddr2_dq[15:0]</obj_property>
@@ -867,6 +863,7 @@
<wvobject fp_name="/toplevel_tb/DUT/ddr_ctrl0/wb_0/ddr_cd_inst/din" type="array" db_ref_id="1">
<obj_property name="ElementShortName">din[63:0]</obj_property>
<obj_property name="ObjectShortName">din[63:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/ddr_ctrl0/wb_0/ddr_cd_inst/dout" type="array" db_ref_id="1">
<obj_property name="ElementShortName">dout[63:0]</obj_property>
@@ -901,6 +898,10 @@
<obj_property name="ElementShortName">fifo_from_sys_empty</obj_property>
<obj_property name="ObjectShortName">fifo_from_sys_empty</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/ddr_ctrl0/wb_0/ddr_cd_inst/fifo_from_sys_almost_empty" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">fifo_from_sys_almost_empty</obj_property>
<obj_property name="ObjectShortName">fifo_from_sys_almost_empty</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/ddr_ctrl0/wb_0/ddr_cd_inst/ddr_address" type="array" db_ref_id="1">
<obj_property name="ElementShortName">ddr_address[22:0]</obj_property>
<obj_property name="ObjectShortName">ddr_address[22:0]</obj_property>