Commit 0596c26b authored by Ricardo Soares Ribolli's avatar Ricardo Soares Ribolli
Browse files

Corrections tp1

parents 9cbf3c51 527dadc7
......@@ -140,6 +140,11 @@ tlm::tlm_response_status LCDC::read(const ensitlm::addr_t &a,
case LCDC_ADDR_REG:
d = addr_register;
break;
/* START CUT */
case LCDC_START_REG:
cerr << name() << ": Write only register (START_REG)!" << endl;
return tlm::TLM_COMMAND_ERROR_RESPONSE;
/* END CUT */
case LCDC_INT_REG:
d = intr_register;
break;
......@@ -158,6 +163,12 @@ tlm::tlm_response_status LCDC::write(const ensitlm::addr_t &a,
case LCDC_ADDR_REG:
addr_register = d;
break;
/* START CUT */
case LCDC_START_REG:
started = true;
start_event.notify();
break;
/* END CUT */
case LCDC_INT_REG:
intr_register = d;
if (intr_register == 0)
......
#include "generator.h"
#include "LCDC_registermap.h"
#include "memmap.h"
#define WIDTH 320
#define HEIGHT 240
#define IMG_SIZE (WIDTH * HEIGHT)
using namespace std;
using namespace sc_core;
Generator::Generator(sc_module_name name) : sc_module(name), irq("irq") {
SC_THREAD(compute);
SC_METHOD(interrupt_handler);
sensitive << irq.pos();
dont_initialize();
interrupt = false;
}
void Generator::compute() {
unsigned i = 0;
test(0);
socket.write(LCDC_BASE + LCDC_ADDR_REG, VRAM_BASE);
socket.write(LCDC_BASE + LCDC_START_REG, 0x000000001);
while (true) {
if (!interrupt)
wait(interrupt_event);
interrupt = false;
cout << name() << ": interrupt caught!" << endl;
socket.write(LCDC_BASE + LCDC_INT_REG, 0x00000000);
// Just to show that the image is moving each time an interrupt is triggered
i = i % HEIGHT;
test(i);
i++;
}
}
void Generator::test(unsigned initvalue) {
ensitlm::addr_t a = VRAM_BASE;
ensitlm::addr_t b = VROM_BASE + initvalue * WIDTH;
ensitlm::data_t rvalue, wval1, wval2;
#ifdef DEBUG
cout << name() << ": test(" << initvalue << ")" << endl;
#endif
for (int y = 0; y < HEIGHT * WIDTH / 8; y++) {
if (b >= (VROM_BASE + IMG_SIZE / 2))
b = b - IMG_SIZE / 2;
socket.read(b, rvalue);
#ifdef DEBUG
cout << name() << ": done read (0x" << hex << b << ", 0x"
<< rvalue << ") /* ROM */;" << endl;
#endif
wval1 = ((rvalue & 0xF0000000)) +
((rvalue & 0x0F000000) >> 4) +
((rvalue & 0x00F00000) >> 8) +
((rvalue & 0x000F0000) >> 12);
wval2 = ((rvalue & 0x0000F000) << 16) +
((rvalue & 0x00000F00) << 12) +
((rvalue & 0x000000F0) << 8) +
((rvalue & 0x0000000F) << 4);
void generator::thread(void) {
ensitlm::data_t val = 1;
ensitlm::addr_t addr = 0x10000000;
for(int i = 0; i < 10; i++) {
val = i;
socket.write(addr, val);
addr++;
socket.write(a, wval1);
#ifdef DEBUG
cout << name() << ": done write(0x" << hex << a << ", 0x"
<< wval1 << ") /* RAM */;" << endl;
#endif
a += 4;
socket.write(a, wval2);
#ifdef DEBUG
cout << name() << ": done write(0x" << hex << a << ", 0x"
<< wval2 << ") /* RAM */;" << endl;
#endif
a += 4;
b += 4;
}
cout << name() << ": finished image" << endl;
}
generator::generator(sc_core::sc_module_name name) : sc_core::sc_module(name) {
SC_THREAD(thread);
void Generator::interrupt_handler() {
interrupt = true;
interrupt_event.notify();
}
#ifndef GENERATOR_H
#define GENERATOR_H
#include "ensitlm.h"
#include "bus.h"
struct generator : sc_core::sc_module {
ensitlm::initiator_socket<generator> socket;
void thread(void);
struct Generator : sc_core::sc_module {
ensitlm::initiator_socket<Generator> socket;
sc_core::sc_in<bool> irq;
SC_CTOR(Generator);
void compute();
void test(unsigned initvalue);
SC_CTOR(generator);
void interrupt_handler();
bool interrupt;
sc_core::sc_event interrupt_event;
};
#endif
#define MEMORY_BASE 0x10000000
#define VRAM_BASE 0x10002800
#define VROM_BASE 0x30000000
#define LCDC_BASE 0x20000000
#include "ensitlm.h"
#include "memory.h"
using namespace std;
// #define DEBUG
tlm::tlm_response_status memory::write(const ensitlm::addr_t &a,
const ensitlm::data_t &d) {
// Constructor
Memory::Memory(sc_core::sc_module_name name, unsigned int size)
: sc_module(name), m_size(size) {
storage = new ensitlm::data_t[size / sizeof(ensitlm::data_t)];
}
cout << "Message reçu: " << d << " from: " << endl;
// Destructor
Memory::~Memory() {
delete[] storage;
}
// Read transactions
tlm::tlm_response_status Memory::read(ensitlm::addr_t a, ensitlm::data_t &d) {
// Check if the address is within memory bounds
if (a >= m_size) {
std::cerr << name() << ": Read access outside memory range! ("
<< a << ")" << std::endl;
return tlm::TLM_ADDRESS_ERROR_RESPONSE;
} else {
d = storage[a / sizeof(ensitlm::data_t)];
#ifdef DEBUG
std::cout << name() << ": Read access at 0x" << hex << a
<< " (Data: 0x" << d << ")" << std::endl;
#endif
return tlm::TLM_OK_RESPONSE;
}
}
tlm::tlm_response_status memory::read(const ensitlm::addr_t &a,
/* */ ensitlm::data_t &d) {
SC_REPORT_ERROR("TLM", "non implémenté");
abort();
// Write transactions
tlm::tlm_response_status Memory::write(ensitlm::addr_t a, ensitlm::data_t d) {
// Check if the address is within memory bounds
if (a >= m_size) {
std::cerr << name() << ": Write access outside memory range! ("
<< a << ")" << std::endl;
return tlm::TLM_ADDRESS_ERROR_RESPONSE;
} else {
#ifdef DEBUG
std::cout << name() << ": Write access at 0x" << hex << a
<< " (Data: 0x" << d << ")" << std::endl;
#endif
storage[a / sizeof(ensitlm::data_t)] = d;
return tlm::TLM_OK_RESPONSE;
}
}
#ifndef MEMORY_H
#define MEMORY_H
#include "ensitlm.h"
struct memory : sc_core::sc_module {
ensitlm::target_socket<memory> socket;
SC_MODULE(Memory) {
ensitlm::target_socket<Memory> target;
SC_HAS_PROCESS(Memory);
Memory(sc_core::sc_module_name name, unsigned int size);
~Memory();
tlm::tlm_response_status write(const ensitlm::addr_t &a,
const ensitlm::data_t &d);
tlm::tlm_response_status read(ensitlm::addr_t a, ensitlm::data_t & d);
tlm::tlm_response_status read(const ensitlm::addr_t &a,
/* */ ensitlm::data_t &d);
SC_CTOR(memory) { /* */ }
tlm::tlm_response_status write(ensitlm::addr_t a, ensitlm::data_t d);
private:
unsigned int m_size;
public:
/* The loader must have access to the storage */
ensitlm::data_t *storage;
};
#endif
#include "ensitlm.h"
#include "generator.h"
#include "bus.h"
#include "memory.h"
#include "LCDC.h"
#include "ROM.h"
#include "bus.h"
#include "memmap.h"
#define RAM_SIZE 0x15400
using namespace sc_core;
int sc_main(int, char **) {
Generator generator1("Generator1");
Memory memory("Memory", RAM_SIZE);
LCDC lcdc("LCDC", sc_time(1.0 / 25, SC_SEC));
ROM rom("ROM");
Bus bus("Bus");
sc_signal<bool, SC_MANY_WRITERS> irq_signal("IRQ");
int sc_main(int argc, char **argv){
(void)argc;
(void)argv;
// initiators
generator1.socket.bind(bus.target);
lcdc.initiator_socket.bind(bus.target);
/* Creation of a Generator and a Bus */
generator g1("Generator1");
Bus b("Bus");
memory m("Memory");
// targets
bus.initiator.bind(memory.target);
bus.initiator.bind(lcdc.target_socket);
bus.initiator.bind(rom.socket);
/* Connexion between generation and bus */
g1.socket.bind(b.target);
/* Connexion between bus and target */
b.initiator.bind(m.socket);
// interrupts
lcdc.display_intr(irq_signal);
generator1.irq(irq_signal);
/* Mapping memory addresses between [0x10000000, 0x100000FF] */
b.map(m.socket, 0x10000000, 0x100);
bus.map(memory.target, MEMORY_BASE, RAM_SIZE);
bus.map(lcdc.target_socket, LCDC_BASE, 12);
bus.map(rom.socket, VROM_BASE, ROM_SIZE);
/* Start the simulation */
sc_core::sc_start();
// start the simulation
sc_start();
return 0;
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment