Pages

Tuesday, 20 December 2011

Aquiring image data from file/memory/port in Verilog - Part II

Acquire image and access:


Let us consider an example where some hardware acquires 8 bits of image data and stores it in the memory. For simplicity, let’s assume that the image is very small say 50 X 37 (that is, there are 50 pixels in a row, let’s call it ‘pixel row’ and there are 37 such ‘pixel rows’ so, 1850 pixels (50 * 37) in total constitute the image). Each pixel is an 8 bit value (ranging from 0 to 255).


With following module and the test bench created by MATLAB in last session 'Aquiring image data from file/memory/port in Verilog - Part I' you can simulate and find out that the image will be stored in hex.

If you need the same photo that I have used then go (copy and paste in browser) to http://www.flickr.com/photos/72479767@N07/6543481245/sizes/t/in/photostream/ and click on 'Download the Thumbnail size of this photo' save as 'poko_50x37.jpg'



module img_mem(clk,out,in,wr
);

parameter col=6'b11_0010; //50
parameter row=6'b10_0101;
parameter data_length=8;

input clk;
//reg [7:0] mem [0:1];
reg [data_length-1:0] mem2 [0:row-1][0:col-1];
output reg [data_length-1:0] out;
input [data_length-1:0] in;
input wr;

//integer i;
reg [5:0] cnt1,cnt2,sizx=row-1,sizy=col-1;



always @ (posedge clk)
begin
if (wr) begin
mem2[cnt1][cnt2] <= in;
if (cnt1 != sizx) begin

if (cnt2 != sizy)
cnt2 <= cnt2 + 1;
else begin
cnt2 <=0; cnt1 <= cnt1 + 1;end
end
else begin
if (cnt2 != sizy)
cnt2 <= cnt2 + 1;
else begin
cnt2<=0; cnt1<=0;
end
end
end
else
out <= mem2[1][1];
end

initial begin

cnt1 <= 0;
cnt2 <= 0;

end

endmodule


Wednesday, 14 December 2011

Vectors & Arrays in Verilog - Part II

2. Arrays- From Vectors to Multidimensional Arrays:

Array:


Two Dimensional Array:

It is very common to Store data in two dimensions. Memories store data in this fashion. One or more bits of data can be stored at one location and the 2-D array may have one or more such data locations.

Loc1

M bits

Loc2

M bits

..

.

Loc N

M bits

Example: 4x8 array


00000011


01010011


01010011


01011111


Array declaration:

reg [7:0] rbus [0:3]; //4x8 register array

wire [7:0] wbus [0:3]; //4x8 wire array


Array Access:

assign whole = rbus[0]; //whole is 8 bit wire itself

//answer would be 00000011


Array Bit Select:

assign bit_sel = wbus[0][0]; //0th bit of byte at 0th location is assigned to 1 bit wire bit_sel

//answer would be 0


Array part Select:

assign part_sel = wbus[1][2:0]; //0 to 2 bits of wbus’ location 1 are assigned to 3 bit wire part_sel

//answer would be 011


Array usage:

//dut:

module array(
input [7:0] word,
output [7:0] wbyte,
output [2:0] wpart,
output wbit
);
wire [7:0] array_mem [0:3];

assign wbyte = array_mem[0];
assign wbit = array_mem[0][0];
assign wpart = array_mem[1][2:0];

assign array_mem [0] = word;
assign array_mem [1] = word;
assign array_mem [2] = word;
assign array_mem [3] = word;
endmodule


//Test_bench:
module array_tb();
reg [7:0] word;
wire [7:0] wbyte;
wire [2:0] wpart;
wire wbit;
array v1(.word(word), .wbyte(wbyte), .wpart(wpart), .wbit(wbit));
initial begin
word = 8'b0000_1010; #10 word = 8'b0101_0011;
#10 word = 8'b0101_0011; #10 word = 8'b0101_1111; end

initial #45 $finish;
initial $monitor("word=%b \t wbyte=%b \t wpart=%b \t wbit=%b",word,wbyte,wpart,wbit);

endmodule


Simulations Results:

word=00001010 wbyte=00001010 wpart=010 wbit=0

word=01010011 wbyte=01010011 wpart=011 wbit=1

word=01011111 wbyte=01011111 wpart=111 wbit=1


Vectors & Arrays in Verilog - Part I

1. Vectors- From Vectors to Multidimensional Arrays:

VECTORS:

How do you handle arrays in Verilog? Many times over it is required to access arrays in Verilog.

What if you had to store data in a memory as matrix? How will you access the elements of the matrix?

First, let’s have a look at Vectors in Verilog:

Vector: Vector has only one dimension. It is also called a bus notation


Vector declaration:

reg [3:0] rbus; //4 bit wide register vector

wire [3:0] wbus; //4 bit wide wire vector


Vector Access:

assign whole = rbus; //whole is 4 bit wire itself


Vector Bit Select:

assign bit_sel = wbus[0]; //0th bit of wbus is assigned to 1 bit wire bit_sel


Vector part Select:

assign part_sel = wbus[2:0]; //0 to 2 bits of wbus are assigned to 3 bit wire part_sel



Vector Usage:

//DUT:

module vector_part_sel(

input [3:0] nibble,

output [2:0] wbus,

output wbit

);

assign wbus = nibble[2:0];

assign wbit = nibble[3];

endmodule


//Test_bench:

module vector_part_sel_tb();

reg [3:0] nibble;

wire [2:0] wbus;

wire wbit;

vector_part_sel v1(.nibble(nibble), .wbus(wbus), .wbit(wbit));

initial begin

nibble = 4'b1010; #10 nibble = 4'b0101;

#10 nibble = 4'b1110; #10 nibble = 4'b0111; end

initial #45 $finish;

initial $monitor("nibble=%b \t wbus=%b \t wbit=%b",nibble,wbus,wbit);

endmodule



Simulation Results:

nibble=1010 wbus=010 wbit=1

nibble=0101 wbus=101 wbit=0

nibble=1110 wbus=110 wbit=1

nibble=0111 wbus=111 wbit=0

Tuesday, 13 December 2011

Aquiring image data from file/memory/port in Verilog - Part I

1. Automated VerilogHDL test-bench generation:


Often, the test-benches need to feed in some unusually large amount of data into the core/DUT. Imagine if you had to write a VerilogHDL test-bench which gets 5000 or more unique data sequences (we will be using this while reading image bytes for an image).

Indeed, creativity it takes to figure out the most efficient and easy way to turn around things. For HDL coding when we talk, it is generating automated and appropriate test-benches.

If one has to read 1850 sequences of input data (like what follows in the session #2) through a test-bench it wouldn’t be wise to hand-code the entire test-bench. Rather, some other languages/way (MATLAB, C etc) may be used to auto-generate the required test-bench file.


If you need the same photo that I have used then go (copy and paste in browser) to http://www.flickr.com/photos/72479767@N07/6543481245/sizes/t/in/photostream/ and click on 'Download the Thumbnail size of this photo' save as 'poko_50x37.jpg'



Take a look at a 60 line MATLAB code that does exactly that. This code generates a .v test-bench file which has approximately 1874 lines:


clc; close all; clear all; moduleNAME='img_mem_tb'; %verilog module name
fileNAME=strcat(moduleNAME,'.v');

Img = imread('poko_50x37.jpg');

YCBCRImg=rgb2ycbcr(Img);

GRAYImg=rgb2gray(YCBCRImg);

figure ,imshow(GRAYImg);

xy = size(GRAYImg);

x=xy(1);

y=xy(2);

delete (fileNAME) %delete older file

delete ('hex.txt')%delete older file

%fid below writes the testbench file for verilog HDL

fid = fopen(fileNAME,, 'a+'); %open to write with append new file

dif = fopen('hex.txt','a+')

fprintf(fid,'module %s;\n',moduleNAME)

fprintf(fid,'parameter data_length=8;\n')

fprintf(fid,'// Inputs\n')

fprintf(fid, 'reg clk;\n')

fprintf(fid, 'reg [data_length-1:0] in;\n')

fprintf(fid, 'reg wr;\n')

fprintf(fid, '// Outputs\n')

fprintf(fid, 'wire [data_length-1:0] out;\n')

fprintf(fid, '// Instantiate the Unit Under Test (UUT)\n')

fprintf(fid, 'img_mem uut (\n')

fprintf(fid, ' .clk(clk), \n')

fprintf(fid, ' .out(out), \n')

fprintf(fid, ' .in(in), \n')

fprintf(fid, ' .wr(wr)\n')

fprintf(fid, ');\n')

fprintf(fid,'always #1 clk=~clk;\n')

fprintf(fid, 'initial begin\n')

fprintf(fid, ' // Initialize Inputs\n')

fprintf(fid, ' clk = 0;\n')

fprintf(fid, ' in = 0;\n')

fprintf(fid, ' wr =1;\n')

for runx=1:1:x

for runy=1:1:y

A=dec2hex(GRAYImg(runx,runy));

fprintf(dif,'%s',A)

fprintf(fid,' #2 in = 8''h ')

fprintf(fid,'%s',A)

fprintf(fid,';');

fprintf(fid,'\n');

end

fprintf(dif,'\n');

end

fprintf(fid, '#2 wr =0;\n')

fprintf(fid, ' end\n')

fprintf(fid, 'endmodule\n')

fclose(fid); % close the verilog testbench file

fclose(dif); % close the hex text file


This embeds the image data in the test-bench as a data (byte) stream just like it would come from a CMOS camera.