- Simulator rasterizer working
- Beginning hardware rasterizer implementation
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "Memory.hh"
|
#include "Memory.hh"
|
||||||
#include "Rasterizer.hh"
|
#include "Rasterizer.hh"
|
||||||
@@ -19,16 +20,57 @@ typedef union {
|
|||||||
uint16_t u16[4];
|
uint16_t u16[4];
|
||||||
} pd;
|
} pd;
|
||||||
|
|
||||||
void Rasterizer::pixel(int x, int y) {
|
void Rasterizer::pixel(unsigned x, unsigned y, uint16_t val) {
|
||||||
cout << "(" << x << "," << y << ")" << endl;
|
//cout << "(" << x << "," << y << ")" << endl;
|
||||||
unsigned adr = ((y*640)+x)/4;
|
unsigned adr = ((y*640)+x)/4;
|
||||||
unsigned ofs = ((y*640)+x)%4;
|
unsigned ofs = ((y*640)+x)%4;
|
||||||
pd data;
|
pd data;
|
||||||
data.u64 = mem_.read(adr);
|
data.u64 = mem_.read(adr);
|
||||||
data.u16[ofs] = 0x0fffu;
|
data.u16[ofs] = val;
|
||||||
mem_.write(adr, data.u64);
|
mem_.write(adr, data.u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Rasterizer::line(unsigned y, unsigned l, unsigned r, unsigned lu, unsigned ru, unsigned lv, unsigned rv) {
|
||||||
|
cout << "line " << y << ": " << l << "->" << r << "(" << lu << "," << ru << "," << lv << "," << rv << ")" << endl;
|
||||||
|
pixel(l,y,((lu/16)<<4)|(lv/16));
|
||||||
|
pixel(r,y,((ru/16)<<4)|(rv/16));
|
||||||
|
unsigned u = lu, v = lv;
|
||||||
|
|
||||||
|
int dx = r-l;
|
||||||
|
unsigned du = abs(lu-ru);
|
||||||
|
unsigned dv = abs(lv-rv);
|
||||||
|
|
||||||
|
int su, sv;
|
||||||
|
if(lu<ru)
|
||||||
|
su = 1;
|
||||||
|
else
|
||||||
|
su = -1;
|
||||||
|
if(lv<rv)
|
||||||
|
sv = 1;
|
||||||
|
else
|
||||||
|
sv = -1;
|
||||||
|
|
||||||
|
int uerr = du-dx;
|
||||||
|
int verr = dv-dx;
|
||||||
|
|
||||||
|
cout << "\t" << dx << "," << du << "," << dv << "," << uerr << "," << verr << endl;
|
||||||
|
for(unsigned x = l+1;x < r;++x) {
|
||||||
|
//cout << "\t\t@" << x << "," << uerr << endl;
|
||||||
|
while(dx && (2*uerr>-dx) && !(2*uerr<du)) {
|
||||||
|
uerr-=dx;
|
||||||
|
u += su;
|
||||||
|
}
|
||||||
|
while(dx && (2*verr>-dx) && !(2*verr<dv)) {
|
||||||
|
verr-=dx;
|
||||||
|
v += sv;
|
||||||
|
}
|
||||||
|
cout << "@("<<x<<","<<y<<"):"<<u<<","<<v<<endl;
|
||||||
|
pixel(x, y, (u&0xf0)|(v>>4));
|
||||||
|
uerr+=du;
|
||||||
|
verr+=dv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Rasterizer::rasterize(triangle t) {
|
void Rasterizer::rasterize(triangle t) {
|
||||||
// sort vertices by y inc, x inc
|
// sort vertices by y inc, x inc
|
||||||
std::sort(t.begin(), t.end(),
|
std::sort(t.begin(), t.end(),
|
||||||
@@ -36,99 +78,207 @@ void Rasterizer::rasterize(triangle t) {
|
|||||||
|
|
||||||
// compute bounding box
|
// compute bounding box
|
||||||
vertex2 ul, lr;
|
vertex2 ul, lr;
|
||||||
ul.x = std::min_element(t.begin(), t.end(),
|
// ul.x = std::min_element(t.begin(), t.end(),
|
||||||
[](vertex2 const& a, vertex2 const& b)->bool{return a.x<b.x;})->x;
|
// [](vertex2 const& a, vertex2 const& b)->bool{return a.x<b.x;})->x;
|
||||||
lr.x = std::max_element(t.begin(), t.end(),
|
// lr.x = std::max_element(t.begin(), t.end(),
|
||||||
[](vertex2 const& a, vertex2 const& b)->bool{return a.x<b.x;})->x;
|
// [](vertex2 const& a, vertex2 const& b)->bool{return a.x<b.x;})->x;
|
||||||
ul.y = std::min_element(t.begin(), t.end(),
|
ul.y = t[0].y;
|
||||||
[](vertex2 const& a, vertex2 const& b)->bool{return a.y<b.y;})->y;
|
lr.y = t[2].y;
|
||||||
lr.y = std::max_element(t.begin(), t.end(),
|
// ul.y = std::min_element(t.begin(), t.end(),
|
||||||
[](vertex2 const& a, vertex2 const& b)->bool{return a.y<b.y;})->y;
|
// [](vertex2 const& a, vertex2 const& b)->bool{return a.y<b.y;})->y;
|
||||||
|
// lr.y = std::max_element(t.begin(), t.end(),
|
||||||
|
// [](vertex2 const& a, vertex2 const& b)->bool{return a.y<b.y;})->y;
|
||||||
|
|
||||||
cout << "Bounding box ("<<ul.x<<","<<ul.y<<")->("<<lr.x<<","<<lr.y<<")"<<endl;
|
//cout << "Bounding box ("<<ul.x<<","<<ul.y<<")->("<<lr.x<<","<<lr.y<<")"<<endl;
|
||||||
|
|
||||||
|
// Draw bounding box
|
||||||
|
// for(unsigned x=ul.x;x <=lr.x;++x) {
|
||||||
|
// pixel(x, ul.y, 0x00f0u);
|
||||||
|
// pixel(x, lr.y, 0x00f0u);
|
||||||
|
// }
|
||||||
|
// for(unsigned y=ul.y;y<=lr.y;++y) {
|
||||||
|
// pixel(ul.x, y, 0x00f0u);
|
||||||
|
// pixel(lr.x, y, 0x00f0u);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Draw vertices
|
||||||
|
// pixel(t[0].x, t[0].y, 0x0f00u);
|
||||||
|
// pixel(t[1].x, t[1].y, 0x0f00u);
|
||||||
|
// pixel(t[2].x, t[2].y, 0x0f00u);
|
||||||
|
|
||||||
// TODO: special case 2 vertices on first line
|
|
||||||
int leftfrom = 0, rightfrom = 0;
|
int leftfrom = 0, rightfrom = 0;
|
||||||
int leftto, rightto;
|
int leftto, rightto;
|
||||||
if(t[1].x>t[2].x) {
|
unsigned left = t[0].x, right = t[0].x;
|
||||||
|
unsigned leftu = t[0].u, rightu = t[0].u;
|
||||||
|
unsigned leftv = t[0].v, rightv = t[0].v;
|
||||||
|
|
||||||
|
if(t[0].y == t[1].y) {
|
||||||
|
// special case: 2 vertices on first line
|
||||||
|
//line(t[0].y, t[0].x, t[1].x, t[0].u, t[1].u, t[0].v, t[1].v);
|
||||||
|
rightfrom = 1;
|
||||||
leftto = 2;
|
leftto = 2;
|
||||||
rightto = 1;
|
|
||||||
} else {
|
|
||||||
leftto = 1;
|
|
||||||
rightto = 2;
|
rightto = 2;
|
||||||
|
right = t[1].x;
|
||||||
|
rightu = t[1].u;
|
||||||
|
rightv = t[1].v;
|
||||||
|
} else {
|
||||||
|
if(t[1].x>t[2].x) {
|
||||||
|
leftto = 2;
|
||||||
|
rightto = 1;
|
||||||
|
} else {
|
||||||
|
leftto = 1;
|
||||||
|
rightto = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pixel(t[0].x,t[0].y);
|
|
||||||
|
|
||||||
int left = t[0].x, right = t[0].x;
|
|
||||||
|
|
||||||
int leftdx = abs(t[leftto].x-t[leftfrom].x);
|
int leftdx = abs(t[leftto].x-t[leftfrom].x);
|
||||||
int leftdy = t[leftto].y-t[leftfrom].y;
|
int leftdy = t[leftto].y-t[leftfrom].y;
|
||||||
|
int leftdu = abs(t[leftto].u-t[leftfrom].u);
|
||||||
|
int leftdv = abs(t[leftto].v-t[leftfrom].v);
|
||||||
int rightdx = abs(t[rightto].x-t[rightfrom].x);
|
int rightdx = abs(t[rightto].x-t[rightfrom].x);
|
||||||
int rightdy = t[rightto].y-t[rightfrom].y;
|
int rightdy = t[rightto].y-t[rightfrom].y;
|
||||||
|
int rightdu = abs(t[rightto].u-t[rightfrom].u);
|
||||||
|
int rightdv = abs(t[rightto].v-t[rightfrom].v);
|
||||||
|
|
||||||
int leftsx, rightsx;
|
int leftsx, leftsu, leftsv, rightsx, rightsu, rightsv;
|
||||||
if(t[leftfrom].x < t[leftto].x)
|
if(t[leftfrom].x < t[leftto].x)
|
||||||
leftsx = 1;
|
leftsx = 1;
|
||||||
else
|
else
|
||||||
leftsx = -1;
|
leftsx = -1;
|
||||||
|
if(t[leftfrom].u < t[leftto].u)
|
||||||
|
leftsu = 1;
|
||||||
|
else
|
||||||
|
leftsu = -1;
|
||||||
|
if(t[leftfrom].v < t[leftto].v)
|
||||||
|
leftsv = 1;
|
||||||
|
else
|
||||||
|
leftsv = -1;
|
||||||
|
|
||||||
if(t[rightfrom].x < t[rightto].x)
|
if(t[rightfrom].x < t[rightto].x)
|
||||||
rightsx = 1;
|
rightsx = 1;
|
||||||
else
|
else
|
||||||
rightsx = -1;
|
rightsx = -1;
|
||||||
int lefterr = leftdx-leftdy;
|
if(t[rightfrom].u < t[rightto].u)
|
||||||
int righterr = rightdx-rightdy;
|
rightsu = 1;
|
||||||
|
else
|
||||||
|
rightsu = -1;
|
||||||
|
if(t[rightfrom].v < t[rightto].v)
|
||||||
|
rightsv = 1;
|
||||||
|
else
|
||||||
|
rightsv = -1;
|
||||||
|
|
||||||
for(int line = ul.y;line < lr.y;++line) {
|
int lefterr = leftdx-leftdy, lefterru = leftdu-leftdy, lefterrv = leftdv-leftdy;
|
||||||
if((leftto == rightto) && (line == t[leftto].y)) {
|
int righterr = rightdx-rightdy, righterru = rightdu-rightdy, righterrv = rightdv-rightdy;
|
||||||
for(int x = left;x <= right;++x)
|
|
||||||
pixel(x, line);
|
line(t[leftfrom].y, t[leftfrom].x, t[rightfrom].x, t[leftfrom].u, t[rightfrom].u, t[leftfrom].v, t[rightfrom].v);
|
||||||
} else {
|
|
||||||
if(line == t[leftto].y) {
|
for(int l = ul.y+1;l <= lr.y;++l) {
|
||||||
leftfrom = leftto;
|
if((l == t[leftto].y) && (l == t[rightto].y) && (leftto != rightto)) {
|
||||||
leftto = (leftto==1)?2:1;
|
assert(l == lr.y);
|
||||||
pixel(t[leftfrom].x, t[leftfrom].y);
|
// special case: 2 vertices on last line
|
||||||
left = t[leftfrom].x;
|
line(l, t[leftto].x, t[rightto].x, t[leftto].u, t[rightto].u, t[leftto].v, t[rightto].v);
|
||||||
|
break;
|
||||||
// reinit
|
}
|
||||||
leftdx = abs(t[leftto].x-t[leftfrom].x);
|
|
||||||
leftdy = abs(t[leftto].y-t[leftfrom].y);
|
while((2*lefterr>-leftdy) && !(2*lefterr<leftdx)) {
|
||||||
if(t[leftfrom].x < t[leftto].x)
|
lefterr-=leftdy;
|
||||||
leftsx = 1;
|
left += leftsx;
|
||||||
else
|
}
|
||||||
leftsx = -1;
|
while((2*lefterru>-leftdy) && !(2*lefterru<leftdu)) {
|
||||||
lefterr = leftdx-leftdy;
|
lefterru-=leftdy;
|
||||||
}
|
leftu += leftsu;
|
||||||
if(line == t[rightto].y) {
|
}
|
||||||
rightfrom = rightto;
|
while((2*lefterrv>-leftdy) && !(2*lefterrv<leftdv)) {
|
||||||
rightto = (rightto==1)?2:1;
|
lefterrv-=leftdy;
|
||||||
pixel(t[rightfrom].x, t[rightfrom].y);
|
leftv += leftsv;
|
||||||
right = t[rightfrom].x;
|
}
|
||||||
|
|
||||||
// reinit
|
while((2*righterr>-rightdy) && !(2*righterr<rightdx)) {
|
||||||
rightdx = abs(t[rightto].x-t[rightfrom].x);
|
righterr-=rightdy;
|
||||||
rightdy = abs(t[rightto].y-t[rightfrom].y);
|
right += rightsx;
|
||||||
if(t[rightfrom].x < t[rightto].x)
|
}
|
||||||
rightsx = 1;
|
while((2*righterru>-rightdy) && !(2*righterru<rightdu)) {
|
||||||
else
|
righterru-=rightdy;
|
||||||
rightsx = -1;
|
rightu += rightsu;
|
||||||
righterr = rightdx-rightdy;
|
}
|
||||||
}
|
while((2*righterrv>-rightdy) && !(2*righterrv<rightdv)) {
|
||||||
|
righterrv-=rightdy;
|
||||||
while(2*lefterr>-leftdy) {
|
rightv += rightsv;
|
||||||
lefterr-=leftdy;
|
}
|
||||||
left += leftsx;
|
|
||||||
}
|
// if(left < ul.x)
|
||||||
while(2*righterr>-rightdy) {
|
// left = ul.x;
|
||||||
righterr-=rightdy;
|
// if(right > lr.x)
|
||||||
right += rightsx;
|
// right = lr.x;
|
||||||
}
|
|
||||||
|
//line(l, left, right, leftu, rightu, leftv, rightv);
|
||||||
for(int x = left;x <= right;++x)
|
|
||||||
pixel(x, line);
|
lefterr += leftdx;
|
||||||
|
lefterru += leftdu;
|
||||||
lefterr += leftdx;
|
lefterrv += leftdv;
|
||||||
righterr += rightdx;
|
|
||||||
}
|
righterr += rightdx;
|
||||||
}
|
righterru += rightdu;
|
||||||
|
righterrv += rightdv;
|
||||||
|
|
||||||
|
if(l == t[leftto].y) {
|
||||||
|
leftfrom = leftto;
|
||||||
|
leftto = (leftto==1)?2:1;
|
||||||
|
//pixel(t[leftfrom].x, t[leftfrom].y);
|
||||||
|
left = t[leftfrom].x;
|
||||||
|
leftu = t[leftfrom].u;
|
||||||
|
leftv = t[leftfrom].v;
|
||||||
|
|
||||||
|
// reinit
|
||||||
|
leftdx = abs(t[leftto].x-t[leftfrom].x);
|
||||||
|
leftdy = t[leftto].y-t[leftfrom].y;
|
||||||
|
leftdu = abs(t[leftto].u-t[leftfrom].u);
|
||||||
|
leftdv = abs(t[leftto].v-t[leftfrom].v);
|
||||||
|
if(t[leftfrom].x < t[leftto].x)
|
||||||
|
leftsx = 1;
|
||||||
|
else
|
||||||
|
leftsx = -1;
|
||||||
|
if(t[leftfrom].u < t[leftto].u)
|
||||||
|
leftsu = 1;
|
||||||
|
else
|
||||||
|
leftsu = -1;
|
||||||
|
if(t[leftfrom].v < t[leftto].v)
|
||||||
|
leftsv = 1;
|
||||||
|
else
|
||||||
|
leftsv = -1;
|
||||||
|
lefterr = leftdx-leftdy;
|
||||||
|
lefterru = leftdu-leftdy;
|
||||||
|
lefterrv = leftdv-leftdy;
|
||||||
|
} else if(l == t[rightto].y) {
|
||||||
|
rightfrom = rightto;
|
||||||
|
rightto = (rightto==1)?2:1;
|
||||||
|
//pixel(t[rightfrom].x, t[rightfrom].y);
|
||||||
|
right = t[rightfrom].x;
|
||||||
|
rightu = t[rightfrom].u;
|
||||||
|
rightv = t[rightfrom].v;
|
||||||
|
|
||||||
|
// reinit
|
||||||
|
rightdx = abs(t[rightto].x-t[rightfrom].x);
|
||||||
|
rightdy = t[rightto].y-t[rightfrom].y;
|
||||||
|
rightdu = abs(t[rightto].u-t[rightfrom].u);
|
||||||
|
rightdv = abs(t[rightto].v-t[rightfrom].v);
|
||||||
|
if(t[rightfrom].x < t[rightto].x)
|
||||||
|
rightsx = 1;
|
||||||
|
else
|
||||||
|
rightsx = -1;
|
||||||
|
if(t[rightfrom].u < t[rightto].u)
|
||||||
|
rightsu = 1;
|
||||||
|
else
|
||||||
|
rightsu = -1;
|
||||||
|
if(t[rightfrom].v < t[rightto].v)
|
||||||
|
rightsv = 1;
|
||||||
|
else
|
||||||
|
rightsv = -1;
|
||||||
|
righterr = rightdx-rightdy;
|
||||||
|
righterru = rightdu-rightdy;
|
||||||
|
righterrv = rightdv-rightdy;
|
||||||
|
}
|
||||||
|
|
||||||
|
line(l, left, right, leftu, rightu, leftv, rightv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,26 +2,29 @@
|
|||||||
#define _SIM_RASTERIZER_HH_
|
#define _SIM_RASTERIZER_HH_
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
class Memory;
|
class Memory;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned x, y;
|
unsigned x, y;
|
||||||
|
unsigned u,v;
|
||||||
} vertex2;
|
} vertex2;
|
||||||
|
|
||||||
typedef std::array<vertex2, 3> triangle;
|
typedef std::array<vertex2, 3> triangle;
|
||||||
|
|
||||||
class Rasterizer {
|
class Rasterizer {
|
||||||
public:
|
public:
|
||||||
Rasterizer(Memory& mem);
|
Rasterizer(Memory& mem);
|
||||||
~Rasterizer();
|
~Rasterizer();
|
||||||
|
|
||||||
void rasterize(triangle t);
|
void rasterize(triangle t);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Memory& mem_;
|
Memory& mem_;
|
||||||
|
|
||||||
void pixel(int x, int y);
|
void pixel(unsigned x, unsigned y, uint16_t val = 0x0fffu);
|
||||||
|
void line(unsigned y, unsigned l, unsigned r, unsigned lu, unsigned ru, unsigned lv, unsigned rv);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ int main(int argc, char *argv[]) {
|
|||||||
cout << "Unable to create surface: " << SDL_GetError() << endl;
|
cout << "Unable to create surface: " << SDL_GetError() << endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
SDL_FillRect(framebuffer, NULL, SDL_MapRGB(framebuffer->format, 0, 255, 255));
|
SDL_FillRect(framebuffer, NULL, SDL_MapRGB(framebuffer->format, 0, 0, 0));
|
||||||
|
|
||||||
|
|
||||||
// Load a bitmap and copy it into simulated DDRRAM
|
// Load a bitmap and copy it into simulated DDRRAM
|
||||||
@@ -65,9 +65,9 @@ int main(int argc, char *argv[]) {
|
|||||||
Rasterizer r(mem);
|
Rasterizer r(mem);
|
||||||
|
|
||||||
cout << "Running..." << endl;
|
cout << "Running..." << endl;
|
||||||
triangle t{{{100, 100},
|
triangle t{{{100, 100, 0, 0},
|
||||||
{150, 200},
|
{150, 200, 255, 0},
|
||||||
{50, 250}}};
|
{50, 250, 0, 255}}};
|
||||||
r.rasterize(t);
|
r.rasterize(t);
|
||||||
|
|
||||||
// return 0;
|
// return 0;
|
||||||
|
|||||||
165
src/bresenham_dp.vhd
Normal file
165
src/bresenham_dp.vhd
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
----------------------------------------------------------------------------------
|
||||||
|
-- Company:
|
||||||
|
-- Engineer:
|
||||||
|
--
|
||||||
|
-- Create Date: 03/22/2013 05:49:49 PM
|
||||||
|
-- Design Name:
|
||||||
|
-- Module Name: bresenham_dp - Behavioral
|
||||||
|
-- Project Name:
|
||||||
|
-- Target Devices:
|
||||||
|
-- Tool Versions:
|
||||||
|
-- Description:
|
||||||
|
--
|
||||||
|
-- Dependencies:
|
||||||
|
--
|
||||||
|
-- Revision:
|
||||||
|
-- Revision 0.01 - File Created
|
||||||
|
-- Additional Comments:
|
||||||
|
--
|
||||||
|
----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
|
||||||
|
-- Uncomment the following library declaration if using
|
||||||
|
-- arithmetic functions with Signed or Unsigned values
|
||||||
|
use IEEE.NUMERIC_STD.ALL;
|
||||||
|
|
||||||
|
-- Uncomment the following library declaration if instantiating
|
||||||
|
-- any Xilinx primitives in this code.
|
||||||
|
--library UNISIM;
|
||||||
|
--use UNISIM.VComponents.all;
|
||||||
|
|
||||||
|
entity bresenham_dp is
|
||||||
|
port(
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
|
||||||
|
x0, x1 : in unsigned(15 downto 0);
|
||||||
|
i0, i1 : in unsigned(15 downto 0);
|
||||||
|
|
||||||
|
load_dx : in std_logic;
|
||||||
|
load_di : in std_logic;
|
||||||
|
init : in std_logic;
|
||||||
|
next_x : out std_logic;
|
||||||
|
done : out std_logic;
|
||||||
|
|
||||||
|
i : out unsigned(15 downto 0);
|
||||||
|
x : out unsigned(15 downto 0));
|
||||||
|
end bresenham_dp;
|
||||||
|
|
||||||
|
architecture Behavioral of bresenham_dp is
|
||||||
|
|
||||||
|
signal neg_dx : signed(15 downto 0) := to_signed(0, 16);
|
||||||
|
signal x1_int : unsigned(15 downto 0) := to_unsigned(0, 16);
|
||||||
|
signal di : signed(15 downto 0) := to_signed(0, 16);
|
||||||
|
signal si : std_logic := '0';
|
||||||
|
|
||||||
|
signal d_sub_1, d_sub_2 : unsigned(15 downto 0) := to_unsigned(0, 16);
|
||||||
|
signal d_sub, d_sub_abs : signed(15 downto 0) := to_signed(0, 16);
|
||||||
|
|
||||||
|
signal err, err_next : signed(15 downto 0) := to_signed(0, 16);
|
||||||
|
signal err_add_1, err_add_2 : signed(15 downto 0) := to_signed(0, 16);
|
||||||
|
signal looping : std_logic := '0';
|
||||||
|
signal err_gt_negdx, err_ge_di : std_logic := '0';
|
||||||
|
|
||||||
|
signal i_int, i_next, i_add : unsigned(15 downto 0) := to_unsigned(0, 16);
|
||||||
|
|
||||||
|
signal x_int : unsigned(15 downto 0) := to_unsigned(0, 16);
|
||||||
|
begin
|
||||||
|
x_reg : process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if load_dx = '1' then
|
||||||
|
neg_dx <= d_sub;
|
||||||
|
x1_int <= x1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process x_reg;
|
||||||
|
|
||||||
|
di_reg : process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if load_di = '1' then
|
||||||
|
di <= d_sub_abs;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process di_reg;
|
||||||
|
|
||||||
|
si_reg : process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if load_di = '1' then
|
||||||
|
si <= d_sub(d_sub'left);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process si_reg;
|
||||||
|
|
||||||
|
d_sub_1 <= x1 when load_dx = '1' else
|
||||||
|
i0;
|
||||||
|
|
||||||
|
d_sub_2 <= x0 when load_dx = '1' else
|
||||||
|
i1;
|
||||||
|
|
||||||
|
d_sub <= signed(d_sub_1) - signed(d_sub_2);
|
||||||
|
|
||||||
|
d_sub_abs <= d_sub when d_sub(d_sub'left) = '0' else
|
||||||
|
-d_sub;
|
||||||
|
|
||||||
|
err_reg : process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
err <= err_next;
|
||||||
|
end if;
|
||||||
|
end process err_reg;
|
||||||
|
|
||||||
|
err_add_1 <= neg_dx when looping = '1' or init = '1' else
|
||||||
|
di;
|
||||||
|
|
||||||
|
err_add_2 <= di when init = '1' else
|
||||||
|
err;
|
||||||
|
|
||||||
|
err_next <= err_add_1 + err_add_2;
|
||||||
|
|
||||||
|
err_gt_negdx <= '1' when (err & "0") > neg_dx else
|
||||||
|
'0';
|
||||||
|
|
||||||
|
err_ge_di <= '1' when (err & "0") >= di else
|
||||||
|
'0';
|
||||||
|
|
||||||
|
looping <= err_gt_negdx and err_ge_di;
|
||||||
|
|
||||||
|
i_reg : process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if init = '1' or looping = '1' then
|
||||||
|
i_int <= i_next;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process i_reg;
|
||||||
|
|
||||||
|
i_add <= i_int + 1 when si = '0' else
|
||||||
|
i_int - 1;
|
||||||
|
|
||||||
|
i_next <= i0 when init = '1' else
|
||||||
|
i_add;
|
||||||
|
|
||||||
|
x_ctr : process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
done <= '0';
|
||||||
|
if load_di = '1' then
|
||||||
|
x_int <= x0;
|
||||||
|
elsif looping = '0' or init = '1' then
|
||||||
|
if x_int = x1_int then
|
||||||
|
done <= '1';
|
||||||
|
end if;
|
||||||
|
x_int <= x_int+1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process x_ctr;
|
||||||
|
|
||||||
|
i <= i_int;
|
||||||
|
x <= x_int;
|
||||||
|
next_x <= not looping;
|
||||||
|
end Behavioral;
|
||||||
Reference in New Issue
Block a user