mirror of
https://github.com/WangXuan95/Hard-JPEG-LS.git
synced 2025-01-17 20:42:53 +08:00
235 lines
7.6 KiB
Verilog
235 lines
7.6 KiB
Verilog
|
|
//--------------------------------------------------------------------------------------------------------
|
|
// Module : tb_jls_encoder
|
|
// Type : simulation, top
|
|
// Standard: Verilog 2001 (IEEE1364-2001)
|
|
// Function: testbench for jls_encoder,
|
|
// load some .pgm files (uncompressed image file), and push them to jls_encoder.
|
|
// get output JPEG-LS stream from jls_encoder, and write them to .jls files (JPEG-LS image file)
|
|
//--------------------------------------------------------------------------------------------------------
|
|
|
|
`timescale 1ps/1ps
|
|
|
|
`define NEAR 1 // NEAR can be 0~7
|
|
|
|
`define FILE_NO_FIRST 1 // first input file number
|
|
`define FILE_NO_FINAL 22 // final input file number
|
|
|
|
|
|
// bubble numbers that insert between pixels
|
|
// when = 0, do not insert bubble
|
|
// when > 0, insert BUBBLE_CONTROL bubbles
|
|
// when < 0, insert random 0~(-BUBBLE_CONTROL) bubbles
|
|
`define BUBBLE_CONTROL (-1)
|
|
|
|
|
|
// the input and output file names' format
|
|
`define FILE_NAME_FORMAT "test%03d"
|
|
|
|
// input file (uncompressed .pgm file) directory
|
|
`define INPUT_PGM_DIR "./images"
|
|
|
|
// output file (compressed .jls file) directory
|
|
`define OUTPUT_JLS_DIR "."
|
|
|
|
|
|
module tb_jls_encoder ();
|
|
|
|
//initial $dumpvars(1, tb_jls_encoder);
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------
|
|
// generate clock and reset
|
|
// -------------------------------------------------------------------------------------------------------------------
|
|
reg rstn = 1'b0;
|
|
reg clk = 1'b0;
|
|
always #50000 clk = ~clk; // 10MHz
|
|
initial begin repeat(4) @(posedge clk); rstn<=1'b1; end
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------
|
|
// signals for jls_encoder_i module
|
|
// -------------------------------------------------------------------------------------------------------------------
|
|
reg i_sof = 0;
|
|
reg [13:0] i_w = 0;
|
|
reg [13:0] i_h = 0;
|
|
reg i_e = 0;
|
|
reg [ 7:0] i_x = 0;
|
|
wire o_e;
|
|
wire o_last;
|
|
wire[15:0] o_data;
|
|
|
|
|
|
|
|
reg [7:0] img [8192*8192-1:0];
|
|
integer w = 0, h = 0;
|
|
|
|
task load_img;
|
|
input [256*8:1] fname;
|
|
reg [256*8-1:0] line;
|
|
integer linelen, depth, scanf_num, fp, i;
|
|
begin
|
|
depth = 0;
|
|
fp = $fopen(fname, "rb");
|
|
if (fp==0) begin
|
|
$display("*** error: could not open file %s", fname);
|
|
$finish;
|
|
end
|
|
linelen = $fgets(line, fp);
|
|
if (line[8*(linelen-2)+:16] != 16'h5035) begin
|
|
$display("*** error: the first line must be P5");
|
|
$fclose(fp);
|
|
$finish;
|
|
end
|
|
scanf_num = $fgets(line, fp);
|
|
scanf_num = $sscanf(line, "%d%d", w, h);
|
|
if(scanf_num == 1) begin
|
|
scanf_num = $fgets(line, fp);
|
|
scanf_num = $sscanf(line, "%d", h);
|
|
end
|
|
scanf_num = $fgets(line, fp);
|
|
scanf_num = $sscanf(line, "%d", depth);
|
|
if (depth!=255) begin
|
|
$display("*** error: images depth must be 255");
|
|
$fclose(fp);
|
|
$finish;
|
|
end
|
|
for (i=0; i<h*w; i=i+1)
|
|
img[i] = $fgetc(fp);
|
|
$fclose(fp);
|
|
end
|
|
endtask
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------
|
|
// task: feed image pixels to jls_encoder_i module
|
|
// arguments:
|
|
// w : image width
|
|
// h : image height
|
|
// bubble_control : bubble numbers that insert between pixels
|
|
// when = 0, do not insert bubble
|
|
// when > 0, insert bubble_control bubbles
|
|
// when < 0, insert random 0~bubble_control bubbles
|
|
// -------------------------------------------------------------------------------------------------------------------
|
|
task feed_img;
|
|
input integer bubble_control;
|
|
integer num_bubble, i;
|
|
begin
|
|
// start feeding a image by assert i_sof for 368 cycles
|
|
repeat(368) begin
|
|
@(posedge clk)
|
|
i_sof <= 1'b1;
|
|
i_w <= w - 1;
|
|
i_h <= h - 1;
|
|
{i_e, i_x} <= 0;
|
|
end
|
|
|
|
// for all pixels of the image
|
|
for(i=0; i<h*w; i=i+1) begin
|
|
|
|
// calculate how many bubbles to insert
|
|
if(bubble_control<0) begin
|
|
num_bubble = $random % (1-bubble_control);
|
|
if(num_bubble<0)
|
|
num_bubble = -num_bubble;
|
|
end else begin
|
|
num_bubble = bubble_control;
|
|
end
|
|
|
|
// insert bubbles
|
|
repeat(num_bubble) @(posedge clk) {i_sof, i_w, i_h, i_e, i_x} <= 0;
|
|
|
|
// assert i_e to input a pixel
|
|
@(posedge clk)
|
|
{i_sof, i_w, i_h} <= 0;
|
|
i_e <= 1'b1;
|
|
i_x <= img[i];
|
|
end
|
|
|
|
// 32 cycles idle between images
|
|
repeat(32) @(posedge clk) {i_sof, i_w, i_h, i_e, i_x} <= 0;
|
|
end
|
|
endtask
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------
|
|
// jls_encoder_i module
|
|
// -------------------------------------------------------------------------------------------------------------------
|
|
jls_encoder #(
|
|
.NEAR ( `NEAR )
|
|
) u_jls_encoder (
|
|
.rstn ( rstn ),
|
|
.clk ( clk ),
|
|
.i_sof ( i_sof ),
|
|
.i_w ( i_w ),
|
|
.i_h ( i_h ),
|
|
.i_e ( i_e ),
|
|
.i_x ( i_x ),
|
|
.o_e ( o_e ),
|
|
.o_last ( o_last ),
|
|
.o_data ( o_data )
|
|
);
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------
|
|
// read images, feed them to jls_encoder_i module
|
|
// -------------------------------------------------------------------------------------------------------------------
|
|
integer file_no; // file number
|
|
reg [256*8:1] input_file_name;
|
|
reg [256*8:1] input_file_format;
|
|
|
|
initial begin
|
|
$sformat(input_file_format , "%s\\%s.pgm", `INPUT_PGM_DIR, `FILE_NAME_FORMAT);
|
|
|
|
while(~rstn) @ (posedge clk);
|
|
|
|
for(file_no=`FILE_NO_FIRST; file_no<=`FILE_NO_FINAL; file_no=file_no+1) begin
|
|
$sformat(input_file_name, input_file_format , file_no);
|
|
|
|
load_img(input_file_name);
|
|
$display("%100s (%5dx%5d)", input_file_name, w, h);
|
|
|
|
if( w < 5 || w > 16384 || h < 1 || h > 16384 ) // image size not supported
|
|
$display(" *** image size not supported ***");
|
|
else
|
|
feed_img(`BUBBLE_CONTROL);
|
|
end
|
|
|
|
repeat(100) @(posedge clk);
|
|
|
|
$finish;
|
|
end
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------
|
|
// write output stream to .jls files
|
|
// -------------------------------------------------------------------------------------------------------------------
|
|
reg [256*8:1] output_file_format;
|
|
initial $sformat(output_file_format, "%s\\%s.jls", `OUTPUT_JLS_DIR, `FILE_NAME_FORMAT);
|
|
reg [256*8:1] output_file_name;
|
|
integer opened = 0;
|
|
integer jls_file = 0;
|
|
|
|
always @ (posedge clk)
|
|
if(o_e) begin
|
|
// the first data of an output stream, open a new file.
|
|
if(opened == 0) begin
|
|
opened = 1;
|
|
$sformat(output_file_name, output_file_format, file_no);
|
|
jls_file = $fopen(output_file_name , "wb");
|
|
end
|
|
|
|
// write data to file.
|
|
if(opened != 0 && jls_file != 0)
|
|
$fwrite(jls_file, "%c%c", o_data[7:0], o_data[15:8]);
|
|
|
|
// if it is the last data of an output stream, close the file.
|
|
if(o_last) begin
|
|
opened = 0;
|
|
$fclose(jls_file);
|
|
end
|
|
end
|
|
|
|
endmodule
|