OpenCores
URL https://opencores.org/ocsvn/warp/warp/trunk

Subversion Repositories warp

[/] [warp/] [rtl/] [tmu_scantrace.v] - Rev 7

Compare with Previous | Blame | View Log

/*
 * Milkymist VJ SoC
 * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
 *
 * This program is free and excepted software; you can use it, redistribute it
 * and/or modify it under the terms of the Exception General Public License as
 * published by the Exception License Foundation; either version 2 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 MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the Exception General Public License for more
 * details.
 *
 * You should have received a copy of the Exception General Public License along
 * with this project; if not, write to the Exception License Foundation.
 */
 
module tmu_scantrace(
	input sys_clk,
	input sys_rst,
 
	output busy,
 
	input pipe_stb_i,
	output pipe_ack_o,
	input [10:0] Y,
	input [10:0] S_X,
	input [10:0] S_U,
	input [10:0] S_V,
	input [10:0] E_X,
	input du_positive,
	input [10:0] du_q,
	input [10:0] du_r,
	input dv_positive,
	input [10:0] dv_q,
	input [10:0] dv_r,
	input [10:0] divisor,
 
	output pipe_stb_o,
	input pipe_ack_i,
	output reg [10:0] P_X,
	output reg [10:0] P_Y,
	output reg [10:0] P_U,
	output reg [10:0] P_V
);
 
reg load;
 
/* Register some inputs */
reg [10:0] E_X_r;
reg du_positive_r;
reg [10:0] du_q_r;
reg [10:0] du_r_r;
reg dv_positive_r;
reg [10:0] dv_q_r;
reg [10:0] dv_r_r;
reg [10:0] divisor_r;
 
always @(posedge sys_clk) begin
	if(load) begin
		P_Y <= Y;
		E_X_r <= E_X;
		du_positive_r <= du_positive;
		du_q_r <= du_q;
		du_r_r <= du_r;
		dv_positive_r <= dv_positive;
		dv_q_r <= dv_q;
		dv_r_r <= dv_r;
		divisor_r <= divisor;
	end
end
 
/* Current point datapath */
reg addD;
reg [11:0] errU;
reg correctU;
reg [11:0] errV;
reg correctV;
always @(posedge sys_clk) begin
	if(load) begin
		P_U = S_U;
		errU = 12'd0;
		P_V = S_V;
		errV = 12'd0;
	end else begin
		if(addD) begin
			errU = errU + du_r_r;
			correctU = (errU[10:0] > {1'b0, divisor_r[10:1]}) & ~errU[11];
			if(du_positive_r) begin
				P_U = P_U + du_q_r;
				if(correctU)
					P_U = P_U + 11'd1;
			end else begin
				P_U = P_U - du_q_r;
				if(correctU)
					P_U = P_U - 11'd1;
			end
			if(correctU)
				errU = errU - {1'b0, divisor_r};
 
			errV = errV + dv_r_r;
			correctV = (errV[10:0] > {1'b0, divisor_r[10:1]}) & ~errV[11];
			if(dv_positive_r) begin
				P_V = P_V + dv_q_r;
				if(correctV)
					P_V = P_V + 11'd1;
			end else begin
				P_V = P_V - dv_q_r;
				if(correctV)
					P_V = P_V - 11'd1;
			end
			if(correctV)
				errV = errV - {1'b0, divisor_r};
		end
	end
end
 
/* X datapath */
reg incX;
always @(posedge sys_clk) begin
	if(load)
		P_X <= S_X;
	else if(incX)
		P_X <= P_X + 11'd1;
end
 
wire reachedE = (P_X == E_X_r);
 
/* FSM-based controller */
 
reg state;
reg next_state;
 
parameter IDLE	= 1'b0;
parameter BUSY	= 1'b1;
 
always @(posedge sys_clk) begin
	if(sys_rst)
		state <= IDLE;
	else
		state <= next_state;
end
 
assign busy = state;
assign pipe_ack_o = ~state;
assign pipe_stb_o = state;
 
always @(*) begin
	next_state = state;
	load = 1'b0;
	addD = 1'b0;
	incX = 1'b0;
 
	case(state)
		IDLE: begin
			if(pipe_stb_i) begin
				load = 1'b1;
				next_state = BUSY;
			end
		end
		BUSY: begin
			if(pipe_ack_i) begin
				if(reachedE)
					next_state = IDLE;
				else begin
					incX = 1'b1;
					addD = 1'b1;
				end
			end
		end
	endcase
end
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.