📄 jpeg_encoder_rev4.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 + -