Line 5... |
Line 5... |
// Project : JPEG Decoder
|
// Project : JPEG Decoder
|
// Belong to :
|
// Belong to :
|
// Author : H.Ishihara
|
// Author : H.Ishihara
|
// E-Mail : hidemi@sweetcafe.jp
|
// E-Mail : hidemi@sweetcafe.jp
|
// HomePage : http://www.sweetcafe.jp/
|
// HomePage : http://www.sweetcafe.jp/
|
// Date : 2007/04/11
|
// Date : 2008/02/27
|
// Rev. : 1.03
|
// Rev. : 2.00
|
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
// Rev. Date Description
|
// Rev. Date Description
|
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
// 1.01 2006/10/01 1st Release
|
// 1.01 2006/10/01 1st Release
|
// 1.02 2006/10/04 Remove a HmOldData register.
|
// 1.02 2006/10/04 Remove a HmOldData register.
|
// When reset, clear a ReadDqtTable register.
|
// When reset, clear a ReadDqtTable register.
|
// 1.03 2007/04/11 Remove JpegDecodeStart
|
// 1.03 2007/04/11 Remove JpegDecodeStart
|
// Exchange StateMachine(Add ImageData)
|
// Exchange StateMachine(Add ImageData)
|
// Remove JpegDecodeStart
|
// Remove JpegDecodeStart
|
//---------------------------------------------------------------------------
|
// 2.00 2008/02/27 Exchange State Machine
|
// $Id:
|
|
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
`timescale 1ps / 1ps
|
`timescale 1ps / 1ps
|
|
|
module jpeg_decode_fsm
|
module jpeg_decode_fsm(
|
(
|
|
rst,
|
rst,
|
clk,
|
clk,
|
|
|
// From FIFO
|
// From FIFO
|
DataInEnable,
|
DataInEnable,
|
DataIn,
|
DataIn,
|
|
|
JpegDecodeIdle, // Deocdeer Process Idle(1:Idle, 0:Run)
|
JpegDecodeIdle, // Deocder Process Idle(1:Idle, 0:Run)
|
|
|
OutWidth,
|
OutWidth,
|
OutHeight,
|
OutHeight,
|
OutBlockWidth,
|
OutBlockWidth,
|
OutEnable,
|
OutEnable,
|
Line 52... |
Line 50... |
DhtTable,
|
DhtTable,
|
DhtCount,
|
DhtCount,
|
DhtData,
|
DhtData,
|
|
|
//
|
//
|
HaffumanEnable,
|
HuffmanEnable,
|
HaffumanTable,
|
HuffmanTable,
|
HaffumanCount,
|
HuffmanCount,
|
HaffumanData,
|
HuffmanData,
|
HaffumanStart,
|
HuffmanStart,
|
|
|
//
|
//
|
ImageEnable,
|
ImageEnable,
|
ImageEnd,
|
|
EnableFF00,
|
|
|
|
//
|
//
|
UseByte,
|
UseByte,
|
UseWord
|
UseWord
|
);
|
);
|
Line 94... |
Line 90... |
output [1:0] DhtTable;
|
output [1:0] DhtTable;
|
output [7:0] DhtCount;
|
output [7:0] DhtCount;
|
output [7:0] DhtData;
|
output [7:0] DhtData;
|
|
|
//
|
//
|
output HaffumanEnable;
|
output HuffmanEnable;
|
output [1:0] HaffumanTable;
|
output [1:0] HuffmanTable;
|
output [3:0] HaffumanCount;
|
output [3:0] HuffmanCount;
|
output [15:0] HaffumanData;
|
output [15:0] HuffmanData;
|
output [7:0] HaffumanStart;
|
output [7:0] HuffmanStart;
|
|
|
//
|
//
|
output ImageEnable;
|
output ImageEnable;
|
input ImageEnd;
|
|
output EnableFF00;
|
|
|
|
//
|
//
|
output UseByte;
|
output UseByte;
|
output UseWord;
|
output UseWord;
|
|
|
|
|
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
// Read Maker from Jpeg Data
|
// Read Maker from Jpeg Data
|
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
reg [1:0] State;
|
// State Machine Parameter
|
reg [3:0] Process;
|
parameter S_Idle = 5'd0;
|
wire StateReadByte;
|
parameter S_GetMarker = 5'd1;
|
wire StateReadWord;
|
parameter S_ImageData = 5'd2;
|
wire ImageEnable;
|
// APP Segment
|
|
parameter S_APPLength = 5'd3;
|
wire ReadSegmentEnd;
|
parameter S_APPRead = 5'd4;
|
|
// DQT Segment
|
parameter Idle = 2'b00;
|
parameter S_DQTLength = 5'd5;
|
parameter GetMarker = 2'b01;
|
parameter S_DQTTable = 5'd6;
|
parameter ReadSegment = 2'b10;
|
parameter S_DQTRead = 5'd7;
|
parameter ImageData = 2'b11;
|
// DHT Segmen
|
|
parameter S_DHTLength = 5'd8;
|
parameter NoProcess = 4'h0;
|
parameter S_DHTTable = 5'd9;
|
parameter SegSOI = 4'h1;
|
parameter S_DHTMakeHm0 = 5'd10;
|
parameter SegAPP = 4'h2;
|
parameter S_DHTMakeHm1 = 5'd11;
|
parameter SegDQT = 4'h3;
|
parameter S_DHTMakeHm2 = 5'd12;
|
parameter SegDHT = 4'h4;
|
parameter S_DHTReadTable = 5'd13;
|
parameter SegSOF0 = 4'h5;
|
// SOS Segment
|
parameter SegSOS = 4'h6;
|
parameter S_SOSLength = 5'd14;
|
parameter SegDRI = 4'h7;
|
parameter S_SOSRead0 = 5'd15;
|
parameter SegRST = 4'h8;
|
parameter S_SOSRead1 = 5'd16;
|
parameter SegEOI = 4'h9;
|
parameter S_SOSRead2 = 5'd17;
|
|
parameter S_SOSRead3 = 5'd18;
|
|
parameter S_SOSRead4 = 5'd19;
|
|
parameter S_SOFLength = 5'd20;
|
|
parameter S_SOFRead0 = 5'd21;
|
|
parameter S_SOFReadY = 5'd22;
|
|
parameter S_SOFReadX = 5'd23;
|
|
parameter S_SOFReadComp = 5'd24;
|
|
parameter S_SOFMakeBlock0 = 5'd25;
|
|
parameter S_SOFMakeBlock1 = 5'd26;
|
|
|
|
reg [4:0] State;
|
|
//wire ImageEnable;
|
|
reg [15:0] ReadCount;
|
|
|
reg [15:0] JpegWidth;
|
reg [15:0] JpegWidth;
|
reg [15:0] JpegHeight;
|
reg [15:0] JpegHeight;
|
|
|
|
reg ReadDqtTable;
|
|
reg [1:0] ReadDhtTable;
|
|
|
|
reg [15:0] HmShift;
|
|
reg [15:0] HmData;
|
|
reg [7:0] HmMax;
|
|
reg [7:0] HmCount;
|
|
reg HmEnable;
|
|
|
|
reg [15:0] JpegBlockWidth;
|
|
reg [15:0] JpegBlockHeight;
|
|
|
|
reg ImageEnable;
|
|
|
always @(posedge clk or negedge rst) begin
|
always @(posedge clk or negedge rst) begin
|
if(!rst) begin
|
if(!rst) begin
|
State <= Idle;
|
State <= S_Idle;
|
Process <= NoProcess;
|
ReadCount <= 16'd0;
|
|
JpegWidth <= 16'd0;
|
|
JpegHeight <= 16'd0;
|
|
ReadDqtTable <= 1'b0;
|
|
ReadDhtTable <= 2'd0;
|
|
HmShift <= 16'd0;
|
|
HmData <= 16'd0;
|
|
HmMax <= 8'd0;
|
|
HmCount <= 8'd0;
|
|
HmEnable <= 1'b0;
|
|
JpegBlockWidth <= 16'd0;
|
|
JpegBlockHeight <= 16'd0;
|
|
ImageEnable <= 1'b0;
|
end else begin
|
end else begin
|
case(State)
|
case(State)
|
Idle: begin
|
S_Idle: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
State <= GetMarker;
|
State <= S_GetMarker;
|
end
|
end
|
Process <= NoProcess;
|
|
end
|
end
|
GetMarker: begin
|
// Get Marker(with Header)
|
|
S_GetMarker: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
State <= ReadSegment;
|
|
case(DataIn[31:16])
|
case(DataIn[31:16])
|
16'hFFD8: begin // SOI Segment
|
16'hFFD8: begin // SOI Segment
|
Process <= SegSOI;
|
State <= S_GetMarker;
|
end
|
end
|
16'hFFE0: begin // APP0 Segment
|
16'hFFE0: begin // APP0 Segment
|
Process <= SegAPP;
|
State <= S_APPLength;
|
end
|
end
|
16'hFFDB: begin // DQT Segment
|
16'hFFDB: begin // DQT Segment
|
Process <= SegDQT;
|
State <= S_DQTLength;
|
end
|
end
|
16'hFFC4: begin // DHT Segment
|
16'hFFC4: begin // DHT Segment
|
Process <= SegDHT;
|
State <= S_DHTLength;
|
end
|
end
|
16'hFFC0: begin // SOF0 Segment
|
16'hFFC0: begin // SOF0 Segment
|
Process <= SegSOF0;
|
State <= S_SOFLength;
|
end
|
end
|
16'hFFDA: begin // SOS Segment
|
16'hFFDA: begin // SOS Segment
|
Process <= SegSOS;
|
State <= S_SOSLength;
|
end
|
end
|
//16'hFFDD: begin // DRI Segment
|
//16'hFFDD: begin // DRI Segment
|
// Process <= SegDRI;
|
// State <= S_DRI;
|
//end
|
//end
|
//16'hFFDx: begin // RSTn Segment
|
//16'hFFDx: begin // RSTn Segment
|
// Process <= SegRST;
|
// State <= S_RST;
|
//end
|
//end
|
//16'hFFD9: begin // EOI Segment
|
//16'hFFD9: begin // EOI Segment
|
// Process <= SegEOI;
|
// State <= S_EOI;
|
//end
|
//end
|
default: begin
|
default: begin
|
Process <= SegAPP;
|
State <= S_APPLength;
|
end
|
|
endcase
|
|
end
|
|
end
|
|
ReadSegment: begin
|
|
if(ReadSegmentEnd == 1'b1) begin
|
|
Process <= NoProcess;
|
|
if(Process == SegSOS) begin
|
|
State <= ImageData;
|
|
end else begin
|
|
State <= GetMarker;
|
|
end
|
|
end
|
|
end
|
|
ImageData: begin
|
|
if(OutEnable & (JpegWidth == OutPixelX +1) & (JpegHeight == OutPixelY +1)) begin
|
|
State <= Idle;
|
|
end
|
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
assign JpegDecodeIdle = (State == Idle);
|
|
assign StateReadByte = 1'b0;
|
|
assign StateReadWord = ((State == GetMarker) & (DataInEnable == 1'b1));
|
|
assign ImageEnable = (State == ImageData);
|
|
|
|
wire ReadNopEnd;
|
|
|
|
assign ReadNopEnd = ((Process == SegSOI) | (Process == SegRST));
|
|
|
|
//--------------------------------------------------------------------------
|
|
// APP Segment
|
// APP Segment
|
// Skip read data!
|
S_APPLength: begin
|
//--------------------------------------------------------------------------
|
|
|
|
reg [1:0] StateAPP;
|
|
reg [15:0] ReadAppCount;
|
|
wire ReadAppByte;
|
|
wire ReadAppWord;
|
|
wire ReadAppEnd;
|
|
|
|
parameter AppIdle = 2'd0;
|
|
parameter AppLength = 2'd1;
|
|
parameter AppRead = 2'd2;
|
|
|
|
always @(posedge clk or negedge rst) begin
|
|
if(!rst) begin
|
|
StateAPP <= AppIdle;
|
|
ReadAppCount <= 16'd0;
|
|
end else begin
|
|
case(StateAPP)
|
|
AppIdle: begin
|
|
if(Process == SegAPP) StateAPP <= AppLength;
|
|
ReadAppCount <= 16'd0;
|
|
end
|
|
AppLength: begin
|
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
ReadAppCount <= DataIn[31:16] -2;
|
ReadCount <= DataIn[31:16] -16'd2;
|
StateAPP <= AppRead;
|
State <= S_APPRead;
|
end
|
end
|
end
|
end
|
AppRead: begin
|
S_APPRead: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
if(ReadAppCount == 1) begin
|
if(ReadCount == 16'd1) begin
|
StateAPP <= AppIdle;
|
State <= S_GetMarker;
|
end else begin
|
end else begin
|
ReadAppCount <= ReadAppCount -1;
|
ReadCount <= ReadCount -16'd1;
|
end
|
|
end
|
end
|
end
|
end
|
endcase
|
|
end
|
|
end
|
end
|
assign ReadAppByte = (StateAPP == AppRead);
|
|
assign ReadAppWord = (StateAPP == AppLength);
|
|
assign ReadAppEnd = ((StateAPP == AppRead) & (DataInEnable == 1'b1) & (ReadAppCount == 1));
|
|
|
|
//--------------------------------------------------------------------------
|
|
// DQT Segment
|
// DQT Segment
|
//--------------------------------------------------------------------------
|
S_DQTLength: begin
|
|
|
reg [1:0] StateDQT;
|
|
reg [15:0] ReadDqtCount;
|
|
wire ReadDqtByte;
|
|
wire ReadDqtWord;
|
|
wire ReadDqtEnd;
|
|
wire ReadDqtEnable;
|
|
wire [7:0] ReadDqtData;
|
|
reg ReadDqtTable;
|
|
|
|
parameter DQTIdle = 2'b00;
|
|
parameter DQTLength = 2'b01;
|
|
parameter DQTTable = 2'b10;
|
|
parameter DQTRead = 2'b11;
|
|
|
|
always @(posedge clk or negedge rst) begin
|
|
if(!rst) begin
|
|
StateDQT <= DQTIdle;
|
|
ReadDqtCount <= 16'h0000;
|
|
ReadDqtTable <= 1'b0;
|
|
end else begin
|
|
case(StateDQT)
|
|
DQTIdle: begin
|
|
if(Process == SegDQT) begin
|
|
StateDQT <= DQTLength;
|
|
end
|
|
ReadDqtCount <= 16'h0000;
|
|
end
|
|
DQTLength: begin
|
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
StateDQT <= DQTTable;
|
State <= S_DQTTable;
|
ReadDqtCount <= DataIn[31:16] -2;
|
ReadCount <= DataIn[31:16] -16'd2;
|
end
|
end
|
end
|
end
|
DQTTable: begin
|
S_DQTTable: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
StateDQT <= DQTRead;
|
State <= S_DQTRead;
|
ReadDqtTable <= DataIn[24];
|
ReadDqtTable <= DataIn[24];
|
ReadDqtCount <= 16'd0;
|
ReadCount <= 16'd0;
|
end
|
end
|
end
|
end
|
DQTRead: begin
|
S_DQTRead: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
if(ReadDqtCount ==63) begin
|
if(ReadCount ==63) begin
|
StateDQT <= DQTIdle;
|
State <= S_GetMarker;
|
end
|
|
ReadDqtCount <= ReadDqtCount +1;
|
|
end
|
end
|
end
|
ReadCount <= ReadCount +16'd1;
|
endcase
|
|
end
|
end
|
end
|
end
|
|
|
assign ReadDqtEnable = StateDQT == DQTRead;
|
|
assign ReadDqtData = DataIn[31:24];
|
|
|
|
assign ReadDqtByte = StateDQT == DQTRead | StateDQT == DQTTable;
|
|
assign ReadDqtWord = StateDQT == DQTLength;
|
|
assign ReadDqtEnd = StateDQT == DQTRead & DataInEnable == 1'b1 & ReadDqtCount ==63;
|
|
|
|
//--------------------------------------------------------------------------
|
|
// DHT Segment
|
// DHT Segment
|
//--------------------------------------------------------------------------
|
S_DHTLength: begin
|
reg [2:0] StateDHT;
|
|
reg [15:0] ReadDhtCount;
|
|
wire ReadDhtByte;
|
|
wire ReadDhtWord;
|
|
wire ReadDhtEnd;
|
|
wire ReadDhtEnable;
|
|
wire [7:0] ReadDhtData;
|
|
reg [1:0] ReadDhtTable;
|
|
|
|
reg [15:0] HmShift;
|
|
reg [15:0] HmData;
|
|
reg [7:0] HmMax;
|
|
reg [7:0] HmCount;
|
|
reg HmEnable;
|
|
|
|
parameter DHTIdle = 3'h0;
|
|
parameter DHTLength = 3'h1;
|
|
parameter DHTTable = 3'h2;
|
|
parameter DHTMakeHm0 = 3'h3;
|
|
parameter DHTMakeHm1 = 3'h4;
|
|
parameter DHTMakeHm2 = 3'h5;
|
|
parameter DHTReadTable = 3'h6;
|
|
|
|
always @(posedge clk or negedge rst)
|
|
begin
|
|
if(!rst) begin
|
|
StateDHT <= DHTIdle;
|
|
ReadDhtCount <= 16'h0000;
|
|
ReadDhtTable <= 2'b00;
|
|
HmEnable <= 1'b0;
|
|
HmShift <= 16'h8000;
|
|
HmData <= 16'h0000;
|
|
HmMax <= 8'h00;
|
|
HmCount <= 8'h00;
|
|
end else begin // if (!rst)
|
|
case(StateDHT)
|
|
DHTIdle: begin
|
|
if(Process == SegDHT) begin
|
|
StateDHT <= DHTLength;
|
|
end
|
|
HmEnable <= 1'b0;
|
|
end
|
|
DHTLength: begin
|
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
StateDHT <= DHTTable;
|
State <= S_DHTTable;
|
ReadDhtCount <= DataIn[31:16];
|
ReadCount <= DataIn[31:16];
|
end
|
end
|
end
|
end
|
DHTTable: begin
|
S_DHTTable: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
StateDHT <= DHTMakeHm0;
|
State <= S_DHTMakeHm0;
|
case(DataIn[31:24])
|
case(DataIn[31:24])
|
8'h00: ReadDhtTable <= 2'b00;
|
8'h00: ReadDhtTable <= 2'b00;
|
8'h10: ReadDhtTable <= 2'b01;
|
8'h10: ReadDhtTable <= 2'b01;
|
8'h01: ReadDhtTable <= 2'b10;
|
8'h01: ReadDhtTable <= 2'b10;
|
8'h11: ReadDhtTable <= 2'b11;
|
8'h11: ReadDhtTable <= 2'b11;
|
endcase
|
endcase
|
end
|
end
|
HmShift <= 16'h8000;
|
HmShift <= 16'h8000;
|
HmData <= 16'h0000;
|
HmData <= 16'h0000;
|
HmMax <= 8'h00;
|
HmMax <= 8'h00;
|
ReadDhtCount <= 0;
|
ReadCount <= 16'd0;
|
end // case: DHTTable
|
end
|
DHTMakeHm0: begin
|
S_DHTMakeHm0: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
StateDHT <= DHTMakeHm1;
|
State <= S_DHTMakeHm1;
|
HmCount <= DataIn[31:24];
|
HmCount <= DataIn[31:24];
|
end
|
end
|
HmEnable <= 1'b0;
|
HmEnable <= 1'b0;
|
end
|
end
|
DHTMakeHm1: begin
|
S_DHTMakeHm1: begin
|
StateDHT <= DHTMakeHm2;
|
State <= S_DHTMakeHm2;
|
HmMax <= HmMax + HmCount;
|
HmMax <= HmMax + HmCount;
|
end
|
end
|
DHTMakeHm2: begin
|
S_DHTMakeHm2: begin
|
if(HmCount != 0) begin
|
if(HmCount != 0) begin
|
HmData <= HmData + HmShift;
|
HmData <= HmData + HmShift;
|
HmCount <= HmCount -1;
|
HmCount <= HmCount -8'd1;
|
end else begin
|
end else begin
|
if(ReadDhtCount == 15) begin
|
if(ReadCount == 15) begin
|
StateDHT <= DHTReadTable;
|
State <= S_DHTReadTable;
|
HmCount <= 8'h00;
|
HmCount <= 8'h00;
|
//HmMax <= HmMax -1;
|
|
end else begin
|
end else begin
|
HmEnable <= 1'b1;
|
HmEnable <= 1'b1;
|
StateDHT <= DHTMakeHm0;
|
State <= S_DHTMakeHm0;
|
ReadDhtCount <= ReadDhtCount +1;
|
ReadCount <= ReadCount +16'd1;
|
end
|
end
|
HmShift <= HmShift >> 1;
|
HmShift <= HmShift >> 1;
|
end
|
end
|
end
|
end
|
DHTReadTable: begin
|
S_DHTReadTable: begin
|
HmEnable <= 1'b0;
|
HmEnable <= 1'b0;
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
if(HmMax == HmCount +1) begin
|
if(HmMax == HmCount +1) begin
|
StateDHT <= DHTIdle;
|
State <= S_GetMarker;
|
end
|
|
HmCount <= HmCount +1;
|
|
end
|
end
|
end
|
HmCount <= HmCount +8'd1;
|
endcase
|
|
end
|
end
|
end
|
end
|
|
|
assign ReadDhtEnable = StateDHT == DHTReadTable;
|
|
assign ReadDhtData = DataIn[31:24];
|
|
|
|
assign ReadDhtByte = StateDHT == DHTTable | StateDHT == DHTMakeHm0 |
|
|
StateDHT == DHTReadTable;
|
|
assign ReadDhtWord = StateDHT == DHTLength;
|
|
assign ReadDhtEnd = StateDHT == DHTReadTable & DataInEnable == 1'b1 & HmMax == HmCount +1;
|
|
|
|
//--------------------------------------------------------------------------
|
|
// SOS Segment
|
// SOS Segment
|
//--------------------------------------------------------------------------
|
S_SOSLength: begin
|
reg [3:0] StateSOS;
|
|
reg [15:0] ReadSosCount;
|
|
wire ReadSosByte;
|
|
wire ReadSosWord;
|
|
wire ReadSosEnd;
|
|
|
|
parameter SOSIdle = 4'h0;
|
|
parameter SOSLength = 4'h1;
|
|
parameter SOSRead0 = 4'h2;
|
|
parameter SOSRead1 = 4'h3;
|
|
parameter SOSRead2 = 4'h4;
|
|
parameter SOSRead3 = 4'h5;
|
|
parameter SOSRead4 = 4'h6;
|
|
|
|
reg EnableFF00;
|
|
|
|
always @(posedge clk or negedge rst)
|
|
begin
|
|
if(!rst) begin
|
|
StateSOS <= SOSIdle;
|
|
ReadSosCount <= 16'h0000;
|
|
EnableFF00 <= 1'b0;
|
|
end else begin
|
|
case(StateSOS)
|
|
SOSIdle: begin
|
|
if(Process == SegSOS) begin
|
|
StateSOS <= SOSLength;
|
|
EnableFF00 <= 1'b1;
|
|
end
|
|
end
|
|
SOSLength: begin
|
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
StateSOS <= SOSRead0;
|
State <= S_SOSRead0;
|
ReadSosCount <= DataIn[31:16];
|
ReadCount <= DataIn[31:16];
|
end
|
end
|
end
|
end
|
SOSRead0: begin
|
S_SOSRead0: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
StateSOS <= SOSRead1;
|
State <= S_SOSRead1;
|
ReadSosCount <= {8'h00,DataIn[31:24]};
|
ReadCount <= {8'h00,DataIn[31:24]};
|
end
|
end
|
end
|
end
|
SOSRead1: begin
|
S_SOSRead1: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
if(ReadSosCount == 1) begin
|
if(ReadCount == 1) begin
|
StateSOS <= SOSRead2;
|
State <= S_SOSRead2;
|
end else begin
|
end else begin
|
ReadSosCount <= ReadSosCount -1;
|
ReadCount <= ReadCount -16'd1;
|
end
|
end
|
end
|
end
|
end
|
end
|
SOSRead2: begin
|
S_SOSRead2: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
StateSOS <= SOSRead3;
|
State <= S_SOSRead3;
|
end
|
end
|
end
|
end
|
SOSRead3: begin
|
S_SOSRead3: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
StateSOS <= SOSRead4;
|
State <= S_SOSRead4;
|
end
|
end
|
end
|
end
|
SOSRead4: begin
|
S_SOSRead4: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
StateSOS <= SOSIdle;
|
State <= S_ImageData;
|
|
ImageEnable <= 1'b1;
|
end
|
end
|
end
|
end
|
endcase
|
|
end
|
|
end
|
|
assign ReadSosByte = StateSOS == SOSRead0 | StateSOS == SOSRead2 | StateSOS == SOSRead3 | StateSOS == SOSRead4;
|
|
assign ReadSosWord = StateSOS == SOSLength | StateSOS == SOSRead1;
|
|
assign ReadSosEnd = DataInEnable == 1'b1 & StateSOS == SOSRead4;
|
|
|
|
//--------------------------------------------------------------------------
|
|
// SOF0 Segment
|
// SOF0 Segment
|
//--------------------------------------------------------------------------
|
S_SOFLength: begin
|
reg [3:0] StateSOF;
|
|
reg [15:0] ReadSofCount;
|
|
wire ReadSofByte;
|
|
wire ReadSofWord;
|
|
wire ReadSofEnd;
|
|
|
|
reg [15:0] JpegBlockWidth;
|
|
reg [15:0] JpegBlockHeight;
|
|
|
|
parameter SOFIdle = 4'h0;
|
|
parameter SOFLength = 4'h1;
|
|
parameter SOFRead0 = 4'h2;
|
|
parameter SOFReadY = 4'h3;
|
|
parameter SOFReadX = 4'h4;
|
|
parameter SOFReadComp = 4'h5;
|
|
parameter SOFMakeBlock0 = 4'H6;
|
|
parameter SOFMakeBlock1 = 4'h7;
|
|
|
|
always @(posedge clk or negedge rst)
|
|
begin
|
|
if(!rst) begin
|
|
StateSOF <= SOFIdle;
|
|
ReadSofCount <= 16'h0000;
|
|
JpegWidth <= 16'h0000;
|
|
JpegHeight <= 16'h0000;
|
|
JpegBlockWidth <= 16'h0000;
|
|
JpegBlockHeight <= 16'h0000;
|
|
end else begin
|
|
case(StateSOF)
|
|
SOFIdle: begin
|
|
if(Process == SegSOF0) begin
|
|
StateSOF <= SOFLength;
|
|
end
|
|
end
|
|
SOFLength: begin
|
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
StateSOF <= SOFRead0;
|
State <= S_SOFRead0;
|
ReadSofCount <= DataIn[31:16];
|
ReadCount <= DataIn[31:16];
|
end
|
end
|
end
|
end
|
SOFRead0: begin
|
S_SOFRead0: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
StateSOF <= SOFReadY;
|
State <= S_SOFReadY;
|
end
|
end
|
end
|
end
|
SOFReadY: begin
|
S_SOFReadY: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
StateSOF <= SOFReadX;
|
State <= S_SOFReadX;
|
JpegHeight <= DataIn[31:16];
|
JpegHeight <= DataIn[31:16];
|
JpegBlockHeight <= DataIn[31:16];
|
JpegBlockHeight <= DataIn[31:16];
|
end
|
end
|
end
|
end
|
SOFReadX: begin
|
S_SOFReadX: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
StateSOF <= SOFReadComp;
|
State <= S_SOFReadComp;
|
JpegWidth <= DataIn[31:16];
|
JpegWidth <= DataIn[31:16];
|
JpegBlockWidth <= DataIn[31:16];
|
JpegBlockWidth <= DataIn[31:16];
|
ReadSofCount <= 16'h0000;
|
ReadCount <= 16'd0;
|
end
|
end
|
end
|
end
|
SOFReadComp: begin
|
S_SOFReadComp: begin
|
if(DataInEnable == 1'b1) begin
|
if(DataInEnable == 1'b1) begin
|
if(ReadSofCount == 9) begin
|
if(ReadCount == 9) begin
|
StateSOF <= SOFMakeBlock0;
|
State <= S_SOFMakeBlock0;
|
end else begin
|
end else begin
|
ReadSofCount <= ReadSofCount +1;
|
ReadCount <= ReadCount +16'd1;
|
end
|
end
|
end
|
end
|
end
|
end
|
SOFMakeBlock0:begin
|
S_SOFMakeBlock0:begin
|
StateSOF <= SOFMakeBlock1;
|
State <= S_SOFMakeBlock1;
|
JpegBlockWidth <= JpegBlockWidth +15;
|
JpegBlockWidth <= JpegBlockWidth +16'd15;
|
JpegBlockHeight <= JpegBlockHeight +15;
|
JpegBlockHeight <= JpegBlockHeight +16'd15;
|
end
|
end
|
SOFMakeBlock1:begin
|
S_SOFMakeBlock1:begin
|
StateSOF <= SOFIdle;
|
State <= S_GetMarker;
|
JpegBlockWidth <= JpegBlockWidth >> 4;
|
JpegBlockWidth <= JpegBlockWidth >> 4;
|
JpegBlockHeight <= JpegBlockHeight >> 4;
|
JpegBlockHeight <= JpegBlockHeight >> 4;
|
end
|
end
|
|
|
|
// Image Process
|
|
S_ImageData: begin
|
|
if(OutEnable & (JpegWidth == (OutPixelX +1)) & (JpegHeight == (OutPixelY +1))) begin
|
|
State <= S_Idle;
|
|
ImageEnable <= 1'b0;
|
|
end
|
|
end
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
assign ReadSofByte = StateSOF == SOFRead0 | StateSOF == SOFReadComp;
|
|
assign ReadSofWord = StateSOF == SOFLength | StateSOF == SOFReadX | StateSOF == SOFReadY ;
|
assign UseByte = (DataInEnable == 1'b1) & ((State == S_APPRead) |
|
assign ReadSofEnd = StateSOF == SOFMakeBlock1;
|
(State == S_DQTRead) | (State == S_DQTTable) |
|
|
(State == S_DHTTable) | (State == S_DHTMakeHm0) | (State == S_DHTReadTable) |
|
|
(State == S_SOSRead0) | (State == S_SOSRead2) | (State == S_SOSRead3) | (State == S_SOSRead4) |
|
|
(State == S_SOFRead0) | (State == S_SOFReadComp)
|
|
);
|
|
assign UseWord = (DataInEnable == 1'b1) & ((State == S_GetMarker) |
|
|
(State == S_APPLength) |
|
|
(State == S_DQTLength) |
|
|
(State == S_DHTLength) |
|
|
(State == S_SOSLength) | (State == S_SOSRead1) |
|
|
(State == S_SOFLength) | (State == S_SOFReadX) | (State == S_SOFReadY)
|
|
);
|
|
|
|
assign JpegDecodeIdle = (State == S_Idle);
|
|
//assign ImageEnable = (State == S_ImageData);
|
|
|
assign OutWidth = JpegWidth;
|
assign OutWidth = JpegWidth;
|
assign OutHeight = JpegHeight;
|
assign OutHeight = JpegHeight;
|
assign OutBlockWidth = JpegBlockWidth[11:0];
|
assign OutBlockWidth = JpegBlockWidth[11:0];
|
|
|
//
|
assign DqtEnable = (State == S_DQTRead);
|
assign UseByte = DataInEnable == 1'b1 & (StateReadByte | ReadAppByte | ReadDqtByte | ReadDhtByte | ReadSosByte | ReadSofByte) ;
|
|
assign UseWord = DataInEnable == 1'b1 & (StateReadWord | ReadAppWord | ReadDqtWord | ReadDhtWord | ReadSosWord | ReadSofWord) ;
|
|
assign ReadSegmentEnd = ReadNopEnd | ReadAppEnd | ReadDqtEnd | ReadDhtEnd | ReadSosEnd | ReadSofEnd ;
|
|
|
|
//
|
|
assign DqtEnable = ReadDqtEnable;
|
|
assign DqtTable = ReadDqtTable;
|
assign DqtTable = ReadDqtTable;
|
assign DqtCount = ReadDqtCount[5:0];
|
assign DqtCount = ReadCount[5:0];
|
assign DqtData = ReadDqtData;
|
assign DqtData = DataIn[31:24];
|
|
|
//
|
assign DhtEnable = (State == S_DHTReadTable);
|
assign DhtEnable = ReadDhtEnable;
|
|
assign DhtTable = ReadDhtTable;
|
assign DhtTable = ReadDhtTable;
|
assign DhtCount = HmCount;
|
assign DhtCount = HmCount;
|
assign DhtData = ReadDhtData;
|
assign DhtData = DataIn[31:24];
|
|
|
//
|
assign HuffmanEnable = HmEnable;
|
assign HaffumanEnable = HmEnable;
|
assign HuffmanTable = ReadDhtTable;
|
assign HaffumanTable = ReadDhtTable;
|
assign HuffmanCount = ReadCount[3:0];
|
assign HaffumanCount = ReadDhtCount[3:0];
|
assign HuffmanData = HmData;
|
assign HaffumanData = HmData;
|
assign HuffmanStart = HmMax;
|
assign HaffumanStart = HmMax;
|
|
|
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|