logo资料库

Verilog大作业图像旋转.doc

第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
资料共9页,剩余部分请下载后查看
Verilog 期末大作业 --实现图片顺时针旋转 90 度
用 C++读取图片,将像素信息存入名为 xiangsu 的 文本文件中,C++代码如下: #include"iostream.h" #include"fstream.h" void main() { short int buf[27]; bool rgb[3]; int n=256*256; ifstream image("lena.bmp",ios::binary); ofstream totxt("xiangsu.txt",ios::binary); image.read((char *)buf,sizeof(buf)); for (int i=0;i
以下为图片旋转电路模块 verilog 代码: //This module is to rotate a BMP picture //of 256*256*24bit by 90 degrees clockwise module rot(image_in,start,rst,clk,image_out); input clk; input rst; input start; input [0:23] image_in; //load pixel of 24 bit output [0:23] image_out; //output pixel of 24 bit wire clk; wire rst; wire [0:23] image_in; reg [0:23] image_out; reg [0:7] countrow; reg [0:7] countcolumn; reg [0:15] number; reg [0:7] row; reg [0:7] column; reg finish; /*when input is done, //row counter //column counter //clock //reset //the row number after rotation //the column number after rotation reg [0:23] reg [0:15] t; its value turns 1,otherwise it remains 0 */ store [0:65535]; //used to store pixels //used as a counter while outputing //reset ,high voltage is effective always @(posedge clk) begin if(rst) begin countrow<=0; countcolumn<=0; finish<=0; // enable,high voltage is effective end else begin if(start) begin if(countcolumn==255)//if column counter arrives to maximum begin if(countrow==255) //if row counter arrives to maxinum begin /*column counter and row counter both arrive to maximum*/ countcolumn<=0; countrow<=0; finish<=1; t<=0; end
//only column counter arrives to maximum else begin countcolumn<=0; countrow<=countrow+1; end end else //neither column counter nor //row counter arrives to maximum begin countcolumn<=countcolumn+1; countrow<=countrow; end end end end always@(countrow or countcolumn or finish) begin /*calculate row and column number after rotation*/ row<=255-countcolumn; column<=countrow; end number<=(row<<8)+column; //calculate the address of register always@(row or column) begin end always@(posedge clk) begin if(start&&(~rst)) begin if(finish&&(t<65536)) //if input is finished begin image_out<=store[t]; //output from register from 1 to 65535 t=t+1; //input is not finished begin image_out<=24'bzzzz_zzzz_zzzz_zzzz_zzzz_zzzz; //output is z store[number]<=image_in; //continue to input end else end end else image_out<=24'bzzzz_zzzz_zzzz_zzzz_zzzz_zzzz; //not enable or reset
end endmodule 以下为测试模块代码: `timescale 100 ns /1 ns module rot_test( ); reg rst,clk,start; reg [23:0] image_input; wire [23:0] image_output; reg [23:0] test_store [0:65535]; integer i,outdata,m; reg k; rot M1 (.image_in(image_input),.start(start), .rst(rst),.clk(clk),.image_out(image_output)); initial begin clk=1'b0; start=1'b0; rst=1'b0; m=0; i=0; k=0; $readmemb("G:/xiangsu.txt",test_store); //read txt file outdata=$fopen("G:/outfile.txt"); #15 rst=1; #20 rst=0; #15 start=1; end always #5 clk=~clk; initial #50 k=1; always @(negedge clk) begin if(k) begin if(i<65536)begin image_input=test_store[i]; i=i+1; m=m+1; end end if(m>65536*2) $finish;
end always @(posedge clk) begin if((k)&&(m>65536)) end begin #1 $fwrite(outdata, image_output[23:16]," "); $fwrite(outdata, image_output[15:8]," "); $fwrite(outdata, image_output[7:0]," "); end endmodule 仿真结束后将旋转后的图片像素信息写入文本文件,内容如下: 用 C++读取 outfile.txt 中的图片旋转后像素信息,生成新的 图片 lenarot.bmp,C++代码如下: #include "iostream.h" #include"fstream.h" void main()
{ } short int buf[27]; int rgb[3]; int n=256*256; char str; ifstream ge("outfile.txt",ios::binary); ifstream past("lena.bmp",ios::binary); ofstream outf("lenarot.bmp",ios::binary); past.read((char *)buf,sizeof(buf)); outf.write((char *)buf,sizeof(buf)); for(int i=0;i>rgb[j]; { str=rgb[j]; outf<
钟周期里的上升沿计算出该像素经过旋转后的位置,并保存到相应的存储器中。经 过 65536 个时钟周期,所有像素输入完成并且都保存到旋转后的相应位置的存储器 中。然后开始输出,按照 0~65535 的顺序输出存储器中的像素信息,每次输出 24bit 数据,每个时钟下降沿将像素信息写到另一个文本文件中,每 8bit 按十进制 保存,经过 65536 个时钟周期完成输出。最后用 C++读取这个文本文件里的像素 信息和原图片里的位图文件头信息,生成旋转后的图片。 成员工作总结 :我负责编写测试模块。利用系统任务$readmemb 将文本文件中的像素信息 读入存储器中,在和魏政鸿商定后,我利用 65536 个存储器,每个存储器存 24 比 特数据,这样方便将数据作为输入信号传给电路,每个时钟节拍,按原始图片的像 素顺序传给旋转电路模块的输入端一个 24 比特的像素数据,用于其处理。比较重 要和关键的一个问题就是掌握输入和输出的开始时刻,因为旋转电路中输入和输出 不是同步的,所以测试模块中要与之对应。我用 i 和 m 进行计数,i 用于记录输入 的进度,m 用于全程计数,在 m〉65536 后开始输出,这样就较简单地实现了输入 和输出的有序进行。编程过程中遇到的一个问题是确定输出的开始时刻,原来写的 不是 65536,结果发现旋转后的像素文本文件中开头出现了 3 个或 6 个 z , 这说明 输入还没完成时就开始输出,输出了高阻。通过做这个大作业,我对 verilog 更加 熟悉了,在和其他组员讨论中也有很大的收获。 :在编写旋转电路模块时,利用行、列计数器记录每次输入的像素处在第几 行和第几列,这样不仅可以方便地监测数据输入进程,更重要的是方便计算旋转后 该像素处在第几行和第几列,并且可以算出应该保存在第几个存储器中。在设计输 入和输出的时序时,考虑到输入的像素并不是按照 0~65535 的顺序保存到存储器 中的,因此,如果所有像素还没有输入完,即还没有都按旋转后的顺序保存到存储 器中就开始输出的话,一些存储器中还没来得及存储数据,这必然会导致输出不正 确,因此采取的方法是先让数据都输入并保存到相应存储器中,在此过程中令输出 一直为高阻,输入全部完成后再进行输出,输入和输出分别占用 256*256=65536 个时钟周期。在写代码的过程中,我更加体会到了行为建模的优越性,只需考虑电 路的功能,而无需考虑具体的电路结构。让我感触很深的一点是语法结构必须严谨 无误,否则会造成意想不到的结果。开始时,我忘记在最后输出的 else 后的两个 语句前后写上 begin end ,没有将两条语句包含成一个语句块,结果导致输出的图 片左上角缺失。后来与同学讨论并改正后,才输出正确的旋转图片。可见,编写程 序时,必须严格遵守语法。还有一点,原来计算寄存器地址时用 256*row+column, 后来听老师讲了这样会生成复杂的乘法器,我就改用移位运算符。我体会到团队合 作的重要性,团队成员之间互相学习、帮助会大大提高工作效率。
分享到:
收藏