Skip to content

Adding VGA, ADC, DAC modules and testbench #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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