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

📄 top_enc_rev4.v

📁 Verilog jpec coder encoder source code
💻 V
字号:
`timescale 1ns / 10ps
// Rev 4:  	-Status/Control Registers Implemented
// 			-Controlability Fully Tested
// 			-Clock DLL implemente
`define BEHAVIOR = 1
module top_enc(clkin, rst, nce, awe, are, data, addr,clkout);

	//
	// Inputs & Outputs
	//
	input clkin;		// 25MHz Clock
	input rst;		// Async Active-Low Reset
	input nce;		// Chip Enable (Ative-Low)
	input awe;		// Async Write Enable
	input are;		// Async Read Enable
	input [5:0] addr;	// Address Input
	
	inout [24:0] data;	// Data Output {toggle,doe[amp,huff],EOB,LC,DATA}
	output clkout;
	
	wire [12:0] din;
	reg dstrb, rd_en;
	reg [5:0] tempcontrol; // asynch updates 
	reg [5:0] control;	// [CLKDIV,LC,ADDR3,ADDR2,ADDR1,ADDR0]
	reg update;	// Can only update control when set to 1
	reg renew; // temp control reg updated
	reg toggle;	// Toggle bit to show valid data in fifo
	reg bp; // block processing

	//in_full, in_empty, out_full, out_empty, lc,
	//dct_comp, qnr_comp, rle_comp, huff_comp,
	//dctin,dctout,qnrin,qnrout,rlein,rleout,huffin,huffout]
	reg [16:0] status; 
	wire eob;
	
	assign rd_clk = ~are & ~nce;

	BUFG wrclkg (.I(~awe & ~nce), .O(wr_clk));

	// 
	// Clock DLL
	//
	CLKDLL dll (
		.CLKIN(clkin),
		.CLKFB(clk0b),
		.RST(~rst),
		.CLK0(clk0),
		.CLK90(),
		.CLK180(),
		.CLK270(),
		.CLK2X(),
		.CLKDV(clk_dv),
		.LOCKED()
	);
	BUFG clk0g (.I(clk0),.O(clk0b));
	assign clk_mux = control[5] ? clk_dv : clk0;
	BUFG clkg (.I(clk_mux), .O(clk));

 	assign clkout = clk;
	
	// 
	// Control Register - Address 16
	//

	always @ (posedge wr_clk or negedge rst)
	begin
		if(~rst)
		begin
			renew <= 1'b0;
			tempcontrol <= 6'h0;
		end
		else if(addr == 6'h10)
		begin
			renew <= 1'b1;
			tempcontrol <= data[5:0]; //{clkdiv,LC,ADDR[3:0]}
		end
		else if(tempcontrol == control)
			renew <= 1'b0;
	end
	
	always @ (posedge clk or negedge rst)
	begin
		if(~rst)
		begin
			control <= 6'h0;
			update <= 1'b1;
		end
		else if(eob) update <= 1'b1;
		else if(update && renew)
		begin
			update <= 1'b0; 
			control <= tempcontrol;
		end
	end
	// 
	// Status Register - Address 32
	//
	wire in_full, in_empty, out_full, out_empty;
	wire [11:0] encstat;
	always @ (posedge clk or negedge rst)
	begin
		if(~rst)
			status <= 13'h0;
		else 
			status <= {control[4],in_full,in_empty,out_full,out_empty,encstat};			
	end
	
	// 
	// Wires
	// 
	
	wire [24:0] dout;		// Output Data
	assign data = (~are & ~nce & addr[5]) ? {8'h0,status} : 
			                (~are & ~nce) ? dout : 25'bz;

	//
	// State Machine for Data Input to Encoder
	// 7/21: only can input 1 block at a time with this
	// configuration. should have capability to stream data
	reg state;
	reg [6:0] icnt;
	reg [5:0] cnt;
	reg up, up_icnt;

	// How many items are in the input FIFO
	always @ (posedge wr_clk or negedge rst)
	begin
		if(~rst)
		begin
   	   		icnt <= 6'h0;
			up_icnt <= 1'b0;
		end
		else if(up && !(&control[3:2]) && !(|addr[5:0])) //!(|addr[5:4]))
		begin
			icnt <= icnt - 7'h3f;
			// To account for extra write to fifo in timing sims
			//icnt <= icnt - 7'h40;
			up_icnt <= 1'b1;
		end
		else if(!up && !(&control[3:2]) && !(|addr[5:4]))
		begin
			up_icnt <= 1'b0;
			icnt <= icnt + 1;
		end
	end
	

	always @ (posedge clk or negedge rst)
	begin
		if(~rst)
		begin
			dstrb <= 1'b0;
			rd_en <= 1'b0;
			state <= 1'b0;
			cnt <= 6'h0;
			bp <= 1'b0;
			up <= 1'b0;
		end
		// Input to Huff Does not Require a block in the FIFO
		else if(&control[3:2]) 
		begin
			case(state)
				1'b0:
				begin
					rd_en <= ~in_empty ? 1'b1 : 1'b0;
					dstrb <= 1'b0;
					state <= ~in_empty ? 1'b1 : 1'b0;
				end
				1'b1:
				begin
					rd_en <= 1'b0;
					dstrb <= 1'b1;
					state <= 1'b0;
				end
			endcase
		end
		// FDCT,QNR,RLE all require full block in FIFO prior to dstrb
		else if(up_icnt && up)
			up <= 1'b0;
		else if((icnt >= 7'h3f) && !bp && !up)
		begin
			bp <= 1'b1;
			state <= 1'b0;
			rd_en <= 1'b0;
			up <= 1'b1;
		end
		else if(bp)
		begin
			bp <= &cnt ? 1'b0 : 1'b1;
			//cnt <= rd_en ? cnt + 1 : cnt;
			cnt <= cnt + 1;
			if(!control[3]) //QNR & FDCT require dstrb 1 clk prior to data
			begin
				case(state)
					1'b0: 
					begin
						rd_en <= 1'b1;
						dstrb <= 1'b1;
						state <= 1'b1;
					end
					1'b1:
					begin
						rd_en <= 1'b1;
						dstrb <= 1'b0;
						state <= 1'b1;
					end
				endcase
			end
			
			else // RLE Requires dstrb at same time as data
			begin
				case(state)
					1'b0:
					begin
						rd_en <= 1'b1;
						dstrb <= 1'b0;
						state <= !cnt ? 1'b1 : 1'b0;
					end
					1'b1:
					begin
						rd_en <= 1'b1;
						dstrb <= 1'b1;
						state <= 1'b0;
					end
				endcase
			end
			
		end
		
		else
		begin
			rd_en <= 1'b0;
			dstrb <= 1'b0;
			state <= 1'b0;
		end
	end	
	
	// 
	// Instantiate Input FIFO
	//
	in_fifo in_fifo(
		.din(data[12:0]), //{LC,DATA}
		.wr_en(~nce),
		.wr_clk(wr_clk && !(|addr[5:4])),
		.rd_en(rd_en),	// Read Enable from state machine
		.rd_clk(clk),
		.ainit(~rst), 	// FIFO reset active high
		.dout(din), 
		.full(in_full),
		.empty(in_empty)
	);

	//
	// Instantiate JPEG Encoder
	//
	wire [19:0] do_enc;	//Output of encoder
	wire [1:0] doe;
	jpeg_encoder enc(
		.clk(clk),
		.rst(rst),
		.lc(control[4]),
		.dstrb(dstrb),
		.din(din[11:0]),
		.addr(control[3:0]),
		.eob(eob),
		.doe(doe),
		.dout(do_enc),
		.encstat(encstat)
	);

	//
	// toggle bit
	//
	assign d = |doe & ~clk;
	always @ (posedge d or negedge rst)
	begin
		if(~rst)
			toggle <= 1'b0;
		else
			toggle <= ~toggle;
	end
	
	// 
	// Instantiate Output FIFO
	// 
	out_fifo out_fifo(
		.din({toggle,eob,doe,control[4],do_enc}), //24-bit
		.wr_en(|doe),
		.wr_clk(~clk),
		.rd_en(~nce),
		.rd_clk(rd_clk && !(|addr[5:4])),
		.ainit(~rst),
		.dout(dout[24:0]),	//24-bit
		.full(out_full),
		.empty(out_empty)
	);

		

endmodule

⌨️ 快捷键说明

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