Skip to content

Commit

Permalink
Initial commit, the test screen already works
Browse files Browse the repository at this point in the history
  • Loading branch information
ZipCPU committed Dec 27, 2017
0 parents commit 6a74575
Show file tree
Hide file tree
Showing 18 changed files with 2,811 additions and 0 deletions.
29 changes: 29 additions & 0 deletions .gitignore
@@ -0,0 +1,29 @@
legal.txt
.svn
xilinx
obj_dir
obj-pc
obj-zip
*.o
*.a
*.vcd
.swp
.*.swp
.*.swo
svn-commit*
*_tb
*_tb.dbl
*dbg.txt
*dump.txt
*debug.txt
tags
cpudefs.h
design.h
octave-workspace
core
*.aux
*.log
*.out
*.ps
*.yslog
*.smt2
19 changes: 19 additions & 0 deletions README.md
@@ -0,0 +1,19 @@
This repository contains a simple [video simulator](bench/cpp/vgasim.cpp). It
takes video inputs from a Verilated [design module](rtl/llvga.v), and draws
them to the screen. All [video modes](bench/cpp/videomode.h) are supported by
simply writing the mode lines to the simulator. The
[simulator](bench/cpp/vgasim.cpp) will then create a window on the screen,
displaying whatever image [your design](rtl/wbvgaframe.v) is producing.

The repository also contains a [test pattern generator](rtl/vgatest.v) modeled
roughly after a standard VGA pattern, although not quite the same.

References to VGA within this module could just as easily refer to any display.
Be careful that you match the proper polarity of the synch pulses.

## License

All of the source code in this repository is released under the
[GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html). If these conditions
are not sufficient for your needs, other licenses terms may be purchased.

93 changes: 93 additions & 0 deletions bench/cpp/Makefile
@@ -0,0 +1,93 @@
.PHONY: all
# Make certain the "all" target is the first and therefore the default target
all:
CXX := g++
OBJDIR := obj-pc
RTLD := ../../rtl
YYMMDD := `date +%Y%m%d`
VOBJDR := $(RTLD)/obj_dir
ifneq ($(VERILATOR_ROOT),)
VERILATOR:=$(VERILATOR_ROOT)/bin/verilator
else
VERILATOR_ROOT ?= $(shell bash -c 'verilator -V|grep VERILATOR_ROOT | head -1 | sed -e " s/^.*=\s*//"')
endif
export $(VERILATOR)
VROOT := $(VERILATOR_ROOT)
VINCD := $(VROOT)/include
VINC := -I$(VINCD) -I$(VINCD)/vltstd -I$(VOBJDR)
INCS := -I$(RTLD)/obj_dir/ -I$(RTLD) -I$(VINCD)
VDEFS := $(shell ./vversion.sh)
FLAGS := -Wall -Og -g $(VDEFS)
GFXFLAGS:= $(GFXFLAGS) `pkg-config gtkmm-3.0 --cflags`
GFXLIBS := `pkg-config gtkmm-3.0 --libs`
CFLAGS := $(GFXFLAGS)
SIMSOURCES:= vgasim.cpp
SIMOBJECTS:= $(addprefix $(OBJDIR)/,$(subst .cpp,.o,$(SIMSOURCES)))
SIMHEADERS:= $(foreach header,$(subst .cpp,.h,$(SIMSOURCES)),$(wildcard $(header)))
VOBJS := $(OBJDIR)/verilated.o $(OBJDIR)/verilated_vcd_c.o
all: main_tb archive

SOURCES := main_tb.cpp vgasim.cpp
HEADERS := image.h testb.h vgasim.h videomode.h image.cpp
#
PROGRAMS := main_tb
# Now the return to the "all" target, and fill in some details
all: $(PROGRAMS)

%.o: $(OBJDIR)/%.o
$(OBJDIR)/%.o: %.cpp
$(mk-objdir)
$(CXX) $(CFLAGS) $(INCS) -c $< -o $@

$(OBJDIR)/%.o: $(VINCD)/%.cpp
$(mk-objdir)
$(CXX) $(FLAGS) $(INCS) -c $< -o $@


MAINOBJS := $(OBJDIR)/main_tb.o
main_tb: $(MAINOBJS) $(SIMOBJECTS) $(VOBJS) $(VOBJDR)/Vwbvgaframe__ALL.a
$(CXX) $(GFXFLAGS) $^ $(VOBJDR)/Vwbvgaframe__ALL.a $(GFXLIBS) -o $@

.PHONY: clean
clean:
rm -f *.vcd
rm -f $(PROGRAMS)
rm -rf $(OBJDIR)/

#
# The "depends" target, to know what files things depend upon. The depends
# file itself is kept in $(OBJDIR)/depends.txt
#
define build-depends
$(mk-objdir)
@echo "Building dependency file"
@$(CXX) $(CFLAGS) $(INCS) -MM $(SOURCES) > $(OBJDIR)/xdepends.txt
@sed -e 's/^.*.o: /$(OBJDIR)\/&/' < $(OBJDIR)/xdepends.txt > $(OBJDIR)/depends.txt
@rm $(OBJDIR)/xdepends.txt
endef

.PHONY: archive
archive:
tar --transform s,^,$(YYMMDD)-bench-cpp/, -chjf $(YYMMDD)-bench-cpp.tjz Makefile *.cpp *.h

.PHONY: depends
depends: tags
$(build-depends)

$(OBJDIR)/depends.txt: depends

#
define mk-objdir
@bash -c "if [ ! -e $(OBJDIR) ]; then mkdir -p $(OBJDIR); fi"
endef


#
# The "tags" target
#
tags: $(SOURCES) $(HEADERS)
@echo "Generating tags"
@ctags $(SOURCES) $(HEADERS)


-include $(OBJDIR)/depends.txt
134 changes: 134 additions & 0 deletions bench/cpp/image.cpp
@@ -0,0 +1,134 @@
////////////////////////////////////////////////////////////////////////////////
//
// Filename: image.cpp
//
// Project: vgasim, a Verilator based VGA simulator demonstration
//
// Purpose: A generic 2D image class
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. (It's in the $(ROOT)/doc directory. Run make with no
// target there if the PDF file isn't present.) If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License: GPL, v3, as defined and found on www.gnu.org,
// http://www.gnu.org/licenses/gpl.html
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
#include <stdlib.h>
#include <assert.h>
#include "image.h"

template<class PIXEL> void IMAGE<PIXEL>::allocbuf(int h, int w) {
int i, sz;

sz = h*w*sizeof(PIXEL)+sizeof(PIXEL *)*h;
m_buf = new unsigned char[sz];
assert(m_buf);

m_img = (PIXEL **)m_buf;
m_data = (PIXEL *)&m_buf[sizeof(PIXEL *)*h];
for(i=0; i<h; i++)
m_img[i] = &m_data[i*w];

m_height = h;
m_width = w;
}


template<class PIXEL> IMAGE<PIXEL>::IMAGE(int h, int w) {
allocbuf(h, w);
}

template<class PIXEL> IMAGE<PIXEL>::IMAGE(IMAGE<PIXEL> *img) {
int sz, i;

allocbuf(img->m_height, img->m_width);
sz = size();
for(i=0; i<sz; i++)
m_data[i] = img->m_data[i];
}

template<class PIXEL> IMAGE<PIXEL> *IMAGE<PIXEL>::crop(int y, int x,
int h, int w) {
IMAGE<PIXEL> *r;
int xp, yp;

assert((h>0)&&(w>0));
assert(y+h <= m_height);
assert(x+w <= m_width);

r = new IMAGE<PIXEL>(h, w);

for(yp=0; yp<h; yp++)
for(xp=0; xp<w; xp++)
r->m_img[yp][xp] = m_img[yp+y][xp+x];
return r;
}

template<class PIXEL> void IMAGE<PIXEL>::zeroize(void) {
int ip, sz;

sz = size();
for(ip=0; ip<sz; ip++)
m_data[ip] = 0;
}

template<class PIXEL> IMAGE<PIXEL> *IMAGE<PIXEL>::copy(void) {
IMAGE<PIXEL> *r;
int ip, sz;

r = new IMAGE<PIXEL>(m_height, m_width);
sz = size();
for(ip=0; ip<sz; ip++)
r->m_data[ip] = m_data[ip];
return r;
}

template<class PIXEL> void IMAGE<PIXEL>::flipy(void) {
int r, c;
PIXEL tmp;

// fprintf(stderr, "FLIPPING-Y (%d, %d)\n", height, width);
for(r=0; r<m_height/2; r++) {
for(c=0; c<m_width; c++) {
tmp = m_img[ r][c];
m_img[ r][c] = m_img[m_height-1-r][c];
m_img[m_height-1-r][c] = tmp;
}
}
}

template<class PIXEL> void IMAGE<PIXEL>::flipx(void) {
int r, c;
PIXEL tmp;

// fprintf(stderr, "FLIPPING-X\n");
for(r=0; r<m_height; r++) {
for(c=0; c<m_width/2; c++) {
tmp = m_img[r][ c];
m_img[r][ c] = m_img[r][m_width-1-c];
m_img[r][m_width-1-c] = tmp;
}
}
}
75 changes: 75 additions & 0 deletions bench/cpp/image.h
@@ -0,0 +1,75 @@
////////////////////////////////////////////////////////////////////////////////
//
// Filename: image.h
//
// Project: vgasim, a Verilator based VGA simulator demonstration
//
// Purpose: A generic image manipulation class with a few features.
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. (It's in the $(ROOT)/doc directory. Run make with no
// target there if the PDF file isn't present.) If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License: GPL, v3, as defined and found on www.gnu.org,
// http://www.gnu.org/licenses/gpl.html
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
#ifndef IMAGE_H
#define IMAGE_H

template<class PIXEL> class IMAGE {
protected:
unsigned char *m_buf;
void allocbuf(int h, int w);
void deallocb(void);
public:
int m_height, m_width;
PIXEL **m_img;
PIXEL *m_data;

IMAGE(int h, int w);
IMAGE(IMAGE *imgp);
~IMAGE() { delete[] m_buf; }
long size(void) const { return m_height*m_width; }
IMAGE *crop(int x, int y, int h, int w);

void zeroize(void);
IMAGE *copy(void);
void flipy(void);
void flipx(void);

int height(void) const { return m_height; }
int cols(void) const { return m_height; }
int width(void) const { return m_width; }
int rows(void) const { return m_width; }
};

typedef IMAGE<unsigned char> UCIMAGE, *PIMAGE;
typedef IMAGE<int> IIMAGE, *PIIMAGE;
typedef IMAGE<double> DIMAGE, *PDIMAGE;
#ifdef COMPLEX_H
typedef IMAGE<COMPLEX> CIMAGE, *PCIMAGE;
#endif

#endif

0 comments on commit 6a74575

Please sign in to comment.