Skip to content

Commit

Permalink
Merge pull request #21 from ErickOF/feature-vga
Browse files Browse the repository at this point in the history
Adding VGA, ADC, DAC modules and testbench
  • Loading branch information
ErickOF authored Jul 6, 2024
2 parents b5b3e3d + 5ca3318 commit 169886d
Show file tree
Hide file tree
Showing 12 changed files with 575 additions and 0 deletions.
27 changes: 27 additions & 0 deletions modules/adc/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Include common Makefile
include ../Makefile

SRCDIR+=../../utils/src
INCDIR+=-I$(SYSTEMC_AMS_HOME)/include -I../utils/include
LIBDIR+=-L$(SYSTEMC_AMS_HOME)/lib-linux64
LIBS+=-lsystemc-ams

# Defining preprocessor directive for debug
ifdef IPS_DEBUG_EN
CFLAGS += -DIPS_DEBUG_EN
LFLAGS += -DIPS_DEBUG_EN
endif # IPS_DEBUG_EN

# Defining preprocessor directive for dumping enable
ifdef IPS_DUMP_EN
CFLAGS += -DIPS_DUMP_EN
LFLAGS += -DIPS_DUMP_EN
endif # IPS_DUMP_EN

# Run the compiled file
run:
@./$(TARGET)

# Show waveform
waveform:
@gtkwave ips_adc.vcd
59 changes: 59 additions & 0 deletions modules/adc/include/adc.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#ifndef IPS_ADC_MODEL_HPP
#define IPS_ADC_MODEL_HPP

#include <systemc-ams.h>
#include "vunit.hpp"


/**
* @brief Analog to Digital Converter module representation
* This module generates a N-bit digital signal based on the [Vmin, Vmax]
* voltage range
*
* @tparam BITS - the number of output bits of the digital code
* @tparam VMIN - lowest voltage value
* @tparam VMAX - highest voltage value
* @tparam VU - voltage unit based on VUnit
*/
template <unsigned int BITS = 8, int VMIN = 0, int VMAX = 5, VUnit VU = VUnit::v>
SCA_TDF_MODULE(adc)
{
protected:
// Min voltage value based on the voltage units
const double V_MIN = static_cast<double>(VMIN) / static_cast<double>(VU);
// Max voltage value based on the voltage units
const double V_MAX = static_cast<double>(VMAX) / static_cast<double>(VU);
// Max digital output code
const double MAX_DIG = static_cast<double>((1 << BITS) - 1);
public:
// Input analog voltage
sca_tdf::sca_in<double> in;
// Output digital code
sca_tdf::sca_out<sc_dt::sc_uint<BITS> > out;

/**
* @brief Construct a new adc object
*
*/
SCA_CTOR(adc) : in("in"), out("out") {
// Propagation time from input to output
set_timestep(sca_core::sca_time(0.1, sc_core::SC_US));
}

/**
* @brief Convert the analog signal into digital signal
* The analog signal in a range from Vmin to Vmax is converted into a N-bit
* digital signal
*
*/
void processing()
{

double normalized_ana_in = (in.read() - V_MIN) / (V_MAX - V_MIN);
unsigned int dig_code = static_cast<unsigned int>(normalized_ana_in * MAX_DIG);

this->out.write(static_cast<sc_dt::sc_uint<BITS> >(dig_code));
}
};

#endif // IPS_ADC_MODEL_HPP
30 changes: 30 additions & 0 deletions modules/adc/include/seq_item_adc.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef IPS_SEQ_ITEM_ADC_HPP
#define IPS_SEQ_ITEM_ADC_HPP

#include <cstdlib>


/**
* @brief This class is used to generate the analog signal for the test
*
* @tparam N
*/
template <unsigned int N>
SCA_TDF_MODULE(seq_item_adc)
{
public:
sca_tdf::sca_out<double> o_ana;
const int MAX_CODE = (1 << N);

SCA_CTOR(seq_item_adc)
{
set_timestep(sca_core::sca_time(0.1, sc_core::SC_US));
}

void processing()
{
this->o_ana.write(static_cast<double>(rand() % MAX_CODE) / MAX_CODE);
}
};

#endif // IPS_SEQ_ITEM_ADC_HPP
43 changes: 43 additions & 0 deletions modules/adc/src/tb_adc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <systemc-ams.h>
#include "adc.hpp"
#include "seq_item_adc.hpp"

#define N 8


int sc_main(int, char*[])
{
// Max number of sequence items to test
const int MAX_SEQ_ITEMS = (1 << N) - 1;

// Signals to connect
sca_tdf::sca_signal<double> s_ana;
sca_tdf::sca_signal<sc_dt::sc_uint<N> > s_dig_out;

// DUT
adc<N> ips_adc("ips_adc");
ips_adc.in(s_ana);
ips_adc.out(s_dig_out);

// Sequence item generator for ADC
seq_item_adc<N> ips_seq_item_adc("ips_seq_item_adc");
ips_seq_item_adc.o_ana(s_ana);

// Dump waveform
sca_util::sca_trace_file* tf = sca_util::sca_create_vcd_trace_file("ips_adc");
sca_util::sca_trace(tf, s_ana, "in");
sca_util::sca_trace(tf, s_dig_out, "out");

// Start time
std::cout << "@" << sc_time_stamp() << std::endl;

// Run test
sc_start(MAX_SEQ_ITEMS * 0.1, SC_US);

// End time
std::cout << "@" << sc_time_stamp() << std::endl;

sca_util::sca_close_vcd_trace_file(tf);

return 0;
};
27 changes: 27 additions & 0 deletions modules/dac/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Include common Makefile
include ../Makefile

SRCDIR+=../../utils/src
INCDIR+=-I$(SYSTEMC_AMS_HOME)/include -I../utils/include
LIBDIR+=-L$(SYSTEMC_AMS_HOME)/lib-linux64
LIBS+=-lsystemc-ams

# Defining preprocessor directive for debug
ifdef IPS_DEBUG_EN
CFLAGS += -DIPS_DEBUG_EN
LFLAGS += -DIPS_DEBUG_EN
endif # IPS_DEBUG_EN

# Defining preprocessor directive for dumping enable
ifdef IPS_DUMP_EN
CFLAGS += -DIPS_DUMP_EN
LFLAGS += -DIPS_DUMP_EN
endif # IPS_DUMP_EN

# Run the compiled file
run:
@./$(TARGET)

# Show waveform
waveform:
@gtkwave ips_dac.vcd
59 changes: 59 additions & 0 deletions modules/dac/include/dac.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#ifndef IPS_DAC_MODEL_HPP
#define IPS_DAC_MODEL_HPP

#include <systemc-ams.h>
#include "vunit.hpp"


/**
* @brief Digital to Analog Converter module representation
* This module generates an analog signal based on the [Vmin, Vmax] voltage
* range
*
* @tparam BITS - the number of output bits of the digital code
* @tparam VMIN - lowest voltage value
* @tparam VMAX - highest voltage value
* @tparam VU - voltage unit based on VUnit
*/
template <unsigned int BITS = 8, int VMIN = 0, int VMAX = 5, VUnit VU = VUnit::v>
SCA_TDF_MODULE(dac)
{
protected:
// Min voltage value based on the voltage units
const double V_MIN = static_cast<double>(VMIN) / static_cast<double>(VU);
// Max voltage value based on the voltage units
const double V_MAX = static_cast<double>(VMAX) / static_cast<double>(VU);
// Max digital output code
const double MAX_DIG = static_cast<double>((1 << BITS) - 1);
public:
// Input digital code
sca_tdf::sca_in<sc_dt::sc_uint<BITS> > in;
// Output analog voltage
sca_tdf::sca_out<double> out;

/**
* @brief Construct a new dac object
*
*/
SCA_CTOR(dac) : in("in"), out("out")
{
// Propagation time from input to output
set_timestep(sca_core::sca_time(0.1, sc_core::SC_US));
}

/**
* @brief Convert the digital signal into analog signal
* The N-bit digital code is converted into an analog signal in a voltage
* range from Vmin to Vmax
*
*/
void processing()
{
double dig_in = static_cast<double>(this->in.read().to_uint());
double ana_out = V_MIN + (dig_in / MAX_DIG) * (V_MAX - V_MIN);

this->out.write(ana_out);
}
};

#endif // IPS_DAC_MODEL_HPP
29 changes: 29 additions & 0 deletions modules/dac/include/seq_item_dac.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef IPS_SEQ_ITEM_DAC_HPP
#define IPS_SEQ_ITEM_DAC_HPP

#include <cstdlib>


/**
* @brief This class is used to generate the digital code for the test
*
* @tparam N
*/
template <unsigned int N>
SCA_TDF_MODULE(seq_item_dac)
{
public:
sca_tdf::sca_out<sc_dt::sc_uint<N> > o_dig;

SCA_CTOR(seq_item_dac)
{
set_timestep(sca_core::sca_time(0.1, sc_core::SC_US));
}

void processing()
{
this->o_dig.write(static_cast<sc_dt::sc_uint<N> >(rand() % (1 << N)));
}
};

#endif // IPS_SEQ_ITEM_DAC_HPP
43 changes: 43 additions & 0 deletions modules/dac/src/tb_dac.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <systemc-ams.h>
#include "dac.hpp"
#include "seq_item_dac.hpp"

#define N 8


int sc_main(int, char*[])
{
// Max number of sequence items to test
const int MAX_SEQ_ITEMS = (1 << N) - 1;

// Signals to connect
sca_tdf::sca_signal<sc_dt::sc_uint<N> > s_dig;
sca_tdf::sca_signal<double> s_ana_out;

// DUT
dac<N> ips_dac("ips_dac");
ips_dac.in(s_dig);
ips_dac.out(s_ana_out);

// Sequence item generator for DAC
seq_item_dac<N> ips_seq_item_dac("ips_seq_item_dac");
ips_seq_item_dac.o_dig(s_dig);

// Dump waveform
sca_util::sca_trace_file* tf = sca_util::sca_create_vcd_trace_file("ips_dac");
sca_util::sca_trace(tf, s_dig, "in");
sca_util::sca_trace(tf, s_ana_out, "out");

// Start time
std::cout << "@" << sc_time_stamp() << std::endl;

// Run test
sc_start(MAX_SEQ_ITEMS * 0.1, SC_US);

// End time
std::cout << "@" << sc_time_stamp() << std::endl;

sca_util::sca_close_vcd_trace_file(tf);

return 0;
};
18 changes: 18 additions & 0 deletions modules/utils/include/vunit.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef IPS_VUnit_HPP
#define IPS_VUnit_HPP


/**
* @brief Presents the voltage units
*
*/
enum class VUnit {
// Normal volts
v = 1,
// Milivolts
mv = 1000,
// Microvolts
uv = 1000000,
};

#endif // IPS_VUnit_HPP
26 changes: 26 additions & 0 deletions modules/vga/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Include common Makefile
include ../Makefile

INCDIR+=-I$(SYSTEMC_AMS_HOME)/include
LIBDIR+=-L$(SYSTEMC_AMS_HOME)/lib-linux64
LIBS+=-lsystemc-ams

# Defining preprocessor directive for debug
ifdef IPS_DEBUG_EN
CFLAGS += -DIPS_DEBUG_EN
LFLAGS += -DIPS_DEBUG_EN
endif # IPS_DEBUG_EN

# Defining preprocessor directive for dumping enable
ifdef IPS_DUMP_EN
CFLAGS += -DIPS_DUMP_EN
LFLAGS += -DIPS_DUMP_EN
endif # IPS_DUMP_EN

# Run the compiled file
run:
@./$(TARGET)

# Show waveform
waveform:
@gtkwave ips_vga.vcd
Loading

0 comments on commit 169886d

Please sign in to comment.