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

📄 jpeg_encoder_rev4.v

📁 Verilog jpec coder encoder source code
💻 V
字号:
`timescale 1ns / 10ps
// Rev4: No Changes from Rev3
//////////////////////////////////////////////////////////////
//	Address Decoding Table
//	
//	ADDR[3:2] (Input)		ADDR[1:0] (Output)
//	---------				---------
//	00 -> DCT				00 -> HUFF
//	01 -> QNR				01 -> RLE
//	10 -> RLE				10 -> QNR
//	11 -> HUFF				11 -> DCT 
//
//////////////////////////////////////////////////////////////

module jpeg_encoder(clk, rst, lc, eob, dstrb, din, addr, dout, doe, encstat);
		
	// 
	// inputs & outputs
	//
	
	input clk;			// System Clock Input
	input rst;			// Asyc Active Low Reset
	input lc;			// Luminance(0)/Chrominance(1) Block
	input dstrb;
	input [11:0] din;	// Data Input
   	input [3:0] addr;	// Address Input	
	
	output eob;			// End of block
	output [1:0] doe;	// Data Output Enable [amp_doe,huff_doe]
	output [19:0] dout;	// Data Output
	output [11:0] encstat;

	
	// 
	// Registers
	// 
	reg dqnr_doe;	// qnr_doe delay 1 clk
	reg dcto, qnro, rleo, huffo; // Status Bits
	
	//
	// Wires
	//
	wire fdct_in, qnr_in, rle_in, huff_in; // mux enables

	// Block Start Signal for Huffman Encoder
	
	wire start, bstart;
	reg istart;

	assign start = huff_in  && !eob? istart : bstart;
	
	//
	// Address Decode
	//

	assign fdct_in = ~addr[3] & ~addr[2];
	assign qnr_in = ~addr[3] & addr[2];
	assign rle_in = addr[3] & ~addr[2];
	assign huff_in = addr[3] & addr[2];

	wire huff_out, rle_out, qnr_out, fdct_out;

	assign huff_out = ~addr[1] & ~addr[0];
	assign rle_out = ~addr[1] & addr[0];
	assign qnr_out = addr[1] & ~addr[0];
	assign fdct_out = addr[1] & addr[0];

	//
	// input multiplexers
	// 
	
	wire [7:0] fdct_din;
	wire [11:0] qnr_din;
	wire [11:0] rle_din;
	wire [7:0] huff_din;
	wire [11:0] amp;
	wire [3:0] size, rlen;
	wire [11:0] fdct_dout;
	wire [10:0] qnr_dout;
	wire [19:0] rle_dout;
	wire [7:0] huff_dout;

	assign fdct_din = fdct_in ? din[ 7:0] : 8'h0;
	assign qnr_din 	= qnr_in  ? din[11:0] : fdct_dout;
	assign rle_din 	= rle_in  ? din[11:0] : {qnr_dout[10],qnr_dout};
	assign huff_din = huff_in ? din[ 7:0] : {rlen,size};

	wire fdct_dstrb, qnr_dstrb, rle_dstrb, huff_dstrb;
	wire fdct_doe, qnr_doe, rle_doe, huff_doe;
	
	assign fdct_dstrb = fdct_in ? dstrb : 1'b0;
	assign qnr_dstrb  = qnr_in  ? dstrb : fdct_doe;
	assign rle_dstrb  = rle_in  ? dstrb : dqnr_doe;
	assign huff_dstrb = huff_in ? dstrb : rle_doe;
	
	//
	// output multiplexers
	//
	
	assign rle_dout = {amp,rlen,size};
	
	assign dout = fdct_out ? {8'h0,fdct_dout} :
				  qnr_out  ? {9'h0,qnr_dout}  :
				  rle_out  ? rle_dout  		  :
				  huff_out ? {amp,huff_dout}: 20'h0;

	assign doe	= fdct_out ? {1'b0,fdct_doe} :
				  qnr_out  ? {1'b0,qnr_doe}  :
				  rle_out  ? {rle_doe,rle_doe}  : 
		  		  huff_out ? {rle_doe,huff_doe} : 2'b0;
		  
	
	//
	// Instantiate DCT
	// 
	
	fdct #(13,8,12)
	fdct(
		.clk(clk),
		.ena(1'b1),
		.rst(rst),
		.dstrb(fdct_dstrb),
		.din(fdct_din),
		.dout(fdct_dout),
		.douten(fdct_doe)
	);
	
	//
	// Instantiate Quantization Tables
	//
	wire [7:0] lum, chr;
	wire [7:0] qnt_val;
	wire [5:0] qnt_cnt;
	
	qlum qlum(
		.qnt_val(lum),
		.qnt_cnt(qnt_cnt)
	);

	qchr qchr(
		.qnt_val(chr),
		.qnt_cnt(qnt_cnt)
	);

	assign qnt_val = lc ? chr : lum;

	//
	// Instantiate QNR
	// 
	jpeg_qnr qnr(
		// Inputs
		.clk(clk),
		.ena(1'b1),
		.rst(rst),
		.dstrb(qnr_dstrb),
		.din(qnr_din),
		.qnt_val(qnt_val),
		// Outputs
		.qnt_cnt(qnt_cnt),
		.dout(qnr_dout),
		.douten(qnr_doe),
		// Test Outputs
		.div0(),
		.ovf(),
		.iq(),
		.rq(),
		.s()
	);

	//
	// Delay qnr_dstrb 1 clk to align with dout
	//

	always @ (posedge clk or negedge rst)
	begin
		if(~rst)
			dqnr_doe <= 1'b0;
		else
			dqnr_doe <= qnr_doe;
	end

	// 
	// Instantiate Run Length Encoder
	//
	jpeg_rle rle(
		// inputs
		.clk(clk),
		.rst(rst),
		.ena(1'b1),
		.dstrb(rle_dstrb),	
		.din(rle_din),
		//outputs
		.size(size),
		.rlen(rlen),
		.amp(amp),
		.douten(rle_doe),
		.bstart(bstart)
	);

	//
	// Instantiate Huffman Encoder
	//
	always @ (posedge clk or negedge rst)
	begin
		if(~rst)
			istart <= 1'b0;
		else if(eob)
			istart <= 1'b1;
		else if(huff_dstrb)
			istart <= 1'b0;				
	end
	
	wire [1:0] tablesel;
	
	assign tablesel = start ? {1'b0,lc} : {1'b1,lc};
	
	huffman_enc huff_enc(
		//Inputs
		.clk(clk),
		.rst(rst),
		.tablesel(tablesel),
		.di(huff_din),
		.die(huff_dstrb),
		.do(huff_dout),
		.doe(huff_doe),
		.busy(),
		.eob(eob)
	);

	//
	// Status Bits Set when respective output enable
	// Cleared when eob
	//
	always @ (posedge clk or negedge rst)
	begin
		if(~rst)
		begin
			dcto <= 1'b0;
			qnro <= 1'b0;
			rleo <= 1'b0;
			huffo<= 1'b0;
		end
		else if(eob)
		begin
			dcto <= 1'b0;
			qnro <= 1'b0;
			rleo <= 1'b0;
			huffo <= 1'b0;
		end
		else
		begin
			if(fdct_doe) dcto <= 1'b1;
			if(qnr_doe) qnro <= 1'b1;
			if(rle_doe) rleo <= 1'b1;
			if(huff_doe) huffo <= 1'b1;
		end
	end

	assign encstat = {dcto, qnro, rleo, huffo, fdct_in, fdct_out, qnr_in, qnr_out, rle_in, rle_out, huff_in, huff_out};
endmodule

⌨️ 快捷键说明

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