⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trace_w_pipe.v

📁 Abstract A new intelligent milometer base on a microcontroller can count the sum. By taking full u
💻 V
字号:
// Copyright (c) Charles HY Cheung, Cornell University
//Draws a trace at the specified coordinates
// MAX 256x1024 drawing area real-time
// Pipeline mode

module TRACE(
input pipeline, //mode of the trace

input CLOCK_60,

//VGA
input VGA_CTRL_CLK,
input VGA_VS,
input VGA_HS,
input [9:0] Coord_X, 
input [9:0] Coord_Y,

input reset,
input stop, //stops trace
input cont_line, //continue after end of trace
input [19:0] acq_rate, //max 1MHz/1MHz
input [20:0] volperdivval, //inverse volts per div modifier
input [20:0] secperdivctr, //secs per div counter
input [9:0] offsetpix, //offset pixels

//trc draw area
input [3:0] xdivs,
input [3:0] ydivs,
input [9:0] xmin,
input [9:0] xmax,
input [9:0] ymin,
input [9:0] ymax,

input [7:0] color_bkg,
input [7:0] color_grid,
input [7:0] color_trace,
input [7:0] color_scrn,

//osc interface
input osc_clk,
input [15:0] osc_raw,
input osc_full,
output reg osc_hold,
output reg osc_clk_e,
output reg [15:0] osc_max_samps,
//input [15:0] osc_out,

//SRAM
output reg [15:0] data_reg,
output reg [17:0] addr_reg,
output reg we,

//to osc acquisition clk
output reg acq_clk,
//RAM
input [15:0] acq_data,
input [15:0] acq_secperdiv,
output reg [15:0] acq_data_addr,
output reg ram_sw,
output reg ram_wren
);

reg [9:0] x0_reg, x1_reg, y0_reg, y1_reg; //grid generation bounds for pipeline

//generates a GRID for graphics display, max 10 divs

wire [9:0] x0 = (pipeline) ? x0_reg : xmin;
wire [9:0] x1 = (pipeline) ? x1_reg : xmax;
wire [9:0] y0 = (pipeline) ? y0_reg : ymin;
wire [9:0] y1 = (pipeline) ? y1_reg : ymax;


//set the resolution from bounds					
wire [9:0] resx = x1 - x0;
wire [9:0] resy = y1 - y0;

//set the number of pixels per div
wire [9:0]  xpxperdiv = resx / ((xdivs>10)?10:xdivs);
wire [9:0] ypxperdiv = resy / ((ydivs>10)?10:ydivs);

//maximum 9 divs lines (10divs) set individually
wire [9:0] xdiv1 = xpxperdiv;
wire [9:0] xdiv2 = (xpxperdiv*2 <= resx)? xpxperdiv*2 : resx;
wire [9:0] xdiv3 = (xpxperdiv*3 <= resx)? xpxperdiv*3 : resx;
wire [9:0] xdiv4 = (xpxperdiv*4 <= resx)? xpxperdiv*4 : resx;
wire [9:0] xdiv5 = (xpxperdiv*5 <= resx)? xpxperdiv*5 : resx;
wire [9:0] xdiv6 = (xpxperdiv*6 <= resx)? xpxperdiv*6 : resx;
wire [9:0] xdiv7 = (xpxperdiv*7 <= resx)? xpxperdiv*7 : resx;
wire [9:0] xdiv8 = (xpxperdiv*8 <= resx)? xpxperdiv*8 : resx;
wire [9:0] xdiv9 = (xpxperdiv*9 <= resx)? xpxperdiv*9 : resx;

wire [9:0] ydiv1 = ypxperdiv;
wire [9:0] ydiv2 = (ypxperdiv*2 <= resy)? ypxperdiv*2 : resy;
wire [9:0] ydiv3 = (ypxperdiv*3 <= resy)? ypxperdiv*3 : resy;
wire [9:0] ydiv4 = (ypxperdiv*4 <= resy)? ypxperdiv*4 : resy;
wire [9:0] ydiv5 = (ypxperdiv*5 <= resy)? ypxperdiv*5 : resy;
wire [9:0] ydiv6 = (ypxperdiv*6 <= resy)? ypxperdiv*6 : resy;
wire [9:0] ydiv7 = (ypxperdiv*7 <= resy)? ypxperdiv*7 : resy;
wire [9:0] ydiv8 = (ypxperdiv*8 <= resy)? ypxperdiv*8 : resy;
wire [9:0] ydiv9 = (ypxperdiv*9 <= resy)? ypxperdiv*9 : resy;

//true if within bounds
wire boxed=(
(rw_x>=x0) && (rw_x<=x1) &&
(rw_y>=y0) && (rw_y<=y1) 
)?1:0;

//true if on the gridlines
wire ongrid =   (rw_y==y0 || rw_y==y1 ||
				 rw_x==x0 || rw_x==x1 ||
				 rw_x==xdiv1+x0 || 
				 rw_x==xdiv2+x0 || 
				 rw_x==xdiv3+x0 || 
				 rw_x==xdiv4+x0 || 
				 rw_x==xdiv5+x0 || 
				 rw_x==xdiv6+x0 || 
				 rw_x==xdiv7+x0 || 
				 rw_x==xdiv8+x0 || 
				 rw_x==xdiv9+x0 || 
				 rw_y==ydiv1+y0 || 
				 rw_y==ydiv2+y0 || 
				 rw_y==ydiv3+y0 || 
				 rw_y==ydiv4+y0 || 
				 rw_y==ydiv5+y0 || 
				 rw_y==ydiv6+y0 || 
				 rw_y==ydiv7+y0 || 
				 rw_y==ydiv8+y0 ||
				 rw_y==ydiv9+y0 	 )?1:0;					

//internal registers
reg			trc_init;	
reg			pipe_init;
reg			pipe_init_start;
reg [3:0]	state;
reg [3:0]	jumpstate;
reg [9:0]	rw_x;			//
reg [9:0]	rw_y;			//temp read/write location
reg	[9:0]	cursor_x, cursor_y; //writing-cursor location
reg [20:0]	count_buffer;	//buffer to count to secperdivctr
reg [19:0]	count_osc;			//max disp_rate divider 1MHz/1MHz (1Hz)
reg			trc_clk;		//speed of trace write
reg [20:0]	wait_count;		//counter for screen redraw in HSVS (512)
reg [15:0]  addr_trace;		//trace location in y px
reg [15:0]  acq_addr_inc;	//increment for pipeline top trace

wire [9:0] offset = (offsetpix<=resy) ? offsetpix : resy ; //large offset handling
wire trace_write = (((osc_raw*resy)/32'd65536)>y1)?0:(
						(trace_pos > y1 || trace_pos < y0) ? 0:1); //if overshoot, do not write trace 
wire [15:0] trace_pos = y1-(osc_raw*resy)/(32'd65536+volperdivval)+offset; //resized position of trace

//states
parameter	loop1=4'd1, update=4'd2, wait_key=4'd3, 
				init1=4'd4, loop2=4'd5, buffer2=4'd6, buffer3=4'd7, loop2a=4'd8,
					loop1a=4'd9, loop2b=4'd10, loop1b=4'd11, loop2c=4'd12, update_top=4'd13;
					

//generate trace display clock
always@(posedge VGA_CTRL_CLK)
begin
	if (reset) begin count_buffer <= 0; trc_clk <= 1; end
	else if (~VGA_VS | ~VGA_HS)
	begin
	trc_clk <= (count_buffer == secperdivctr) ? 1 : 0;
	count_buffer <= (count_buffer == secperdivctr) ? 0 : count_buffer + 1;
	end
end

//generate sampling clock from osc
always@(posedge osc_clk or posedge reset)
begin
if (reset)
	begin
		count_osc <= 0;
		acq_clk <= 1;
	end
else 
	begin
		acq_clk <= (count_osc == acq_rate) ? 1 : 0;
		count_osc <= (count_osc == acq_rate) ? 0 : count_osc + 1;
	end
end

wire ram_write = (((acq_data*resy)/32'd65536)>y1)?0:(
						(ram_pos > y1 || ram_pos < y0) ? 0:1); //if overshoot, do not write trace 
wire [15:0] ram_pos = y1-(acq_data*resy)/(32'd65536+volperdivval); 

always@(posedge VGA_CTRL_CLK)
begin
	if	(reset) 
	begin
		//init ram
		ram_sw <= 0;	
		ram_wren <= 0;	
		acq_data_addr <= 0;
		osc_hold <= 1;
		//init pipe draw window
		x0_reg = 10;
		x1_reg = 630;
		y0_reg = 250;
		y1_reg = 470;
		//clr screen
		rw_x = Coord_X; rw_y = Coord_Y;
		addr_reg <= {rw_x[9:1],rw_y[8:0]} ;	// [17:0]
		we 		 <= boxed ? 1'b1 : 1'b0;		//write some memory
		if (rw_x[0]) data_reg[15:8] <= color_scrn; 
		else		data_reg[7:0] <= color_scrn;
		cursor_x <= x0; //write-cursor x at first column
		wait_count <= 0;
		jumpstate <= init1;
		if (~pipeline)
		begin 
		pipe_init <= 0;
		trc_init <= 1;	
		end
		else
		begin
		pipe_init <= 1;
		pipe_init_start <=1;
		trc_init <= 0;
		end
	end

	else if (trc_init & ~stop)
	begin
		rw_x = Coord_X; rw_y = Coord_Y;
		// write grid
		addr_reg <= {rw_x[9:1],rw_y[8:0]} ;	// [17:0]
		we 		 <= boxed ? 1'b0 : 1'b1;			//write some memory in box
		if (rw_x[0]) data_reg[15:8] <= (ongrid? color_grid : color_bkg); 
		else 			data_reg[7:0] <= (ongrid? color_grid : color_bkg);
		
		if (boxed) wait_count <= wait_count + 1;
		if (wait_count == (resx+1)*(resy+1) )	
			begin
			trc_init <= 0;
			wait_count <= 0;
			osc_clk_e <= 1;
			state <= jumpstate;
			end
	end	
	
	//intialize pipeline
	else if (pipe_init & ~stop)
	begin
		if (pipe_init_start == 1)
			begin
			//set adddr scan rate for top trace
			acq_addr_inc <= 65536/resx;
			//set osc to sample & hold
			osc_clk_e <= 1;
			osc_max_samps <= 16'hFFFF;
			osc_hold <= 0;
			//set 
			end
		else if (osc_full) //done sampling
		begin
			ram_sw <= 1; //set ram in read mode (ram_wren is 0)
			trc_init <= 1;
			pipe_init <= 0;
		end
		pipe_init_start <= 0; //started indicator
	end	
		
	//modify display during sync
	else if ((~VGA_VS | ~VGA_HS) & ~stop & ~pipeline & trc_clk)  //sync is active low
	begin
		case(state)
		
			init1: //init
			begin
				we <= 1'b1; //no mem write
				state <= loop1;
			end
			
			loop1:
			begin 
				rw_x = cursor_x; rw_y = {1'd0, trace_pos[8:0]}; //update from trace
				we <= trace_write ? 1'b0 : 1'b1; //mem write depends bounded trace
				addr_reg <= {rw_x[9:1], rw_y[8:0]}; //write location
				if (rw_x[0]) data_reg[15:8] <= color_trace; 
				else 		  data_reg[7:0] <= color_trace; 
				state <= update;	
			end
			
			//Writing-Cursor location update
			//End-Of-Line checking
			update: 
			begin
				we <= 1'b1; //no mem write
				if (cursor_x < x1) // EOL not reached
					begin
					cursor_x <= cursor_x + 10'd1; //increment x cursor
					end
				else
					begin // EOL reached
					cursor_x <= x0; //write-cursor x at first column
					end			
				state <= wait_key; //restart testing
			end
			
			wait_key: //wait for pushbutton before refreshing
			begin
				if (cursor_x == x1)
				begin
					if (cont_line)	trc_init <= 1;
				end
				else	state <= loop1;
			end						
		endcase
	end

	else if ((~VGA_VS | ~VGA_HS) & ~stop & pipeline & trc_clk)  //sync is active low
	begin
		case (state)
			init1: //init
			begin
				we <= 1'b1; //no mem write
				rw_x = cursor_x; rw_y = {1'd0, ram_pos[8:0]-240};
				we <= ram_write ? 1'b0 : 1'b1;
				addr_reg <= {rw_x[9:1], rw_y[8:0]}; //write location
				if (rw_x[0]) data_reg[15:8] <= color_trace; 
				else 		  data_reg[7:0] <= color_trace; 				
				state <= update_top;
			end
			
			//Writing-Cursor location update
			//End-Of-Line checking
			update_top: 
			begin
				we <= 1'b1; //no mem write
				if (cursor_x < x1) // EOL not reached
					begin
					cursor_x <= cursor_x + 10'd1; //increment x cursor
					acq_data_addr <= acq_data_addr + acq_addr_inc;
					state <= init1; //continue trace
					end
				else
					begin // EOL reached
					cursor_x <= x0;//write-cursor x at first column
					acq_data_addr <= 0; //reset addr
					state <= loop1; //trace bottom
					end			
			end

			loop1:
			begin 
				we <= 1'b1; //no mem write
				rw_x = cursor_x; rw_y = {1'd0, ram_pos[8:0]}; //update from trace
				we <= trace_write ? 1'b0 : 1'b1;
				addr_reg <= {rw_x[9:1], rw_y[8:0]}; //write location
				if (rw_x[0]) data_reg[15:8] <= color_trace; 
				else 		  data_reg[7:0] <= color_trace; 
				state <= update;	
			end
			
			//Writing-Cursor location update
			//End-Of-Line checking
			update: 
			begin
				we <= 1'b1; //no mem write
				if (cursor_x < x1) // EOL not reached
					begin
					cursor_x <= cursor_x + 10'd1; //increment x cursor
					acq_data_addr <= acq_data_addr + acq_secperdiv;
					end
				else
					begin // EOL reached
					cursor_x <= x0; //write-cursor x at first column
					end			
				state <= wait_key; //restart testing
			end
			
			wait_key: //wait for pushbutton before refreshing
			begin
				if (cursor_x == x1)
				begin
					if (cont_line)	
					begin
					trc_init <= 1;
					jumpstate <= loop1;
					end
				end
				else	state <= loop1;
			end		
									
		endcase		
	end

	//show display when not blanking, 
	//which implies we=1 (not enabled); and use VGA module address
	else
	begin
		we <= 1'b1;
		addr_reg <= {Coord_X[9:1],Coord_Y[8:0]} ;
	end

end




endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -