深 圳 大 学 实 验 报 告
课程名称: 数字系统现场集成技术
实验项目名称: 自动售货机设计与实现
学院: 信息工程学院
专业: 集成电路设计与集成系统
指导教师:
报告人: 学号: 班级:
同组人: 学号: 班级: 实验时间:
实验报告提交时间:
一、实验目的
1、进一步熟悉ISE软件的使用,熟悉FPGA开发流程; 2、掌握编写fpga代码的步骤,学会绘制ASM图; 3、学会调用ip核实现系统的设计。
二、实验设备
1、装有ISE软件的PC机一台;2、nexys2开发板一块。 三、实验内容与要求
设计一个秒表
基本要求:该实验为团队协作,2人一个小组。可以对3种不同种类的货物进行自动售货,价格分别为A=4.00, B=2.50, C=1.00。售货机可以接受10元,5元,1元三种硬币(即有三种输入信号SY,WY,IY),并且在7段数码管(二位代表元,一位代表角)显示已投入的总钱数,选择货物的输入信号Ia,Ib,Ic,输出指示信号为 Sa, Sb ,Sc 分别表示售出相应的货物,同时输出的信号yuan, jiao代表找零,并显示在7段数码管上。
高级要求(可选):VGA显示3种货物图片及其价格,鼠标点击购买数量(1-9)后显示总价,安规格说明2中的button2-button4输入硬币,VGA显示已投入的总钱数,鼠标点击购买后,显示找零数目,购买物品闪烁,交易完成。 规格说明:
1. 按一下button1按钮,表示购买货物A,第一个LED灯亮;按两下button1按钮,表示购买货物B,第二个LED灯亮;按三下button1按钮,表示购买货物C,第三个LED灯亮,同时7段数码管显示所要购买货物的价格。
2. LED灯亮后,开始输入硬币。button2按一下,输入10元,按两下,输入二十元,以此类推;Button3按一下输入5元,按两下输入10元,以此类推;button4按一下输入1元,按两下输入2元,以此类推。7段数码管显示已投入的总钱数,再次按下button1键,7段数码管显示找零数目,同时指示货物的LED灯熄灭。
3. 如果投入的钱币不够就按下button1键确认购买,数码管显示“ER”。 4. 本实验使用FPGA板:nexys2(建project时,需要选择该芯片的型号)。
四、实验步骤
1、设计系统框图,设计采取自上而下的设计方案,整个秒表系统的原理图如下所示。主要包括四个模块——分频模块、vga协议模块、鼠标、vga数据处理模块。而vga数据处理模块里面又有好几个模块 –有vga数码管显示模块,显示地址模块(用来生成地址给rom的),还有好多各rom的显示模块,板子按键的处理模块以及鼠标按键的处理模块。
总的RTL图
分频器 Vga协议 Vga数据处理 Mouse
Vga数据处理 总体
2、所编写的代码如下。
------------------------顶层文件----程序主代码------------------------------------------ module top_2( clear, clk, rst_p,
key_1yuan, key_5yuan, key_10yuan, video_r, video_g, video_b, ps2clk, ps2data, hsync, vsync, );
input clear; input clk; input rst_p;
input key_1yuan; input key_5yuan; input key_10yuan; inout ps2clk; inout ps2data;
wire rst_n;
assign rst_n=~rst_p; output [2:0] video_r; output [2:0] video_g; output [1:0] video_b; output hsync; output vsync;
wire clk_25M; wire [9:0] x; wire [9:0] y;
wire [7:0] vga_rgb; wire [7:0]mousergb; wire [9:0]mousex; wire [9:0]mousey; wire left_button; wire right_button;
wire data;
mouse u1ps2mouse ( .clk_sys(clk_25M), .reset(rst_p), .ps2_clk(ps2clk), .ps2_data(ps2data),
.left_button(left_button), .right_button(right_button), .mousex(mousex), .mousey(mousey) );
div #(.counter(32'b1)) div_2 (
.inclk(clk), .rst_n(rst_n), .outclk(clk_25M) );
// xiaofk a(
// .clk(clk_25M), // .rst_n(rst_n), // .x(x), // .y(y),
// .rgb(vga_rgb) // );
vga_picture_all vga_picture_all ( .clk(clk_25M), .rst_n(rst_n), .mx(mousex), .my(mousey), .left_button(left_button), .right_button(right_button), .key_1yuan(key_1yuan), .key_5yuan(key_5yuan), .key_10yuan(key_10yuan), .vga_x(x),
.vga_y(y), .vga_rgb(vga_rgb) );
VGA_protocol VGA_protocol ( .video_clk(clk_25M), .rst_n(rst_n), //ram interface .video_rgb(vga_rgb), .video_x(x), //point coordinate .video_y(y), //VGA transfer .video_hsync(hsync), .video_vsync(vsync), .video_en(en_vga), .video_r(video_r), .video_g(video_g), .video_b(video_b) );
endmodule ------------------------------------------------------------------------------------
-------------------------------以下是每个模块的代码---------------------------------------- -------------------------------------- 分频 ----------------------------------------------------------- module div # (parameter counter = 32'd1) (inclk,rst_n,outclk); input inclk; input rst_n;
output reg outclk; wire outclk_pre; reg [31:0]cnt;
wire [31:0]cnt_pre;
always@(posedge inclk or negedge rst_n) begin
if(!rst_n) begin outclk<=0; cnt<=1; end else
begin
outclk<=outclk_pre;
cnt<=cnt_pre; end end
assign cnt_pre=(cnt==counter ? 1'b1:(cnt+1'b1)); assign outclk_pre=(cnt==counter ? ~outclk:outclk);
endmodule -----------------------------------------------------------------------------
------------------------------鼠标----------------------------------- library IEEE;
use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity mouse is Port (
clk_sys : in std_logic; reset : in std_logic;
ps2_clk : inout std_logic; ps2_data : inout std_logic; left_button : out std_logic; right_button : out std_logic;
mousex: inout std_logic_vector(9 downto 0); mousey: inout std_logic_vector(9 downto 0) );
end mouse;
architecture Behavioral of mouse is
constant TOTAL_BITS : integer :=33; -- 数据包位数
constant WATCHDOG : integer :=320; -- 400usec 所需 sys_clk 脉冲数
type m2statetype is (m2_reset, m2_wait, m2_gather, m2_verify, m2_use, m2_hold_clk_l, m2_data_low_1, m2_data_high_1, m2_data_low_2, m2_data_high_2, m2_data_low_3, m2_data_high_3, m2_error_no_ack, m2_await_response); signal m2_state,m2_next_state : m2statetype;
signal watchdog_timer_done : std_logic;--命令传输超时标志 signal q : std_logic_vector(TOTAL_BITS-1 downto 0);--位序列 signal bitcount : std_logic_vector(5 downto 0);--位计数器
signal watchdog_timer_count : std_logic_vector(8 downto 0); --等待时间 signal ps2_clk_hi_z : std_logic; signal ps2_data_hi_z : std_logic;
signal fallsig,risesig : std_logic_vector(2 downto 0);
signal clean_clk : std_logic; -- 从 m1 跟随 ps2_clk 反向输出 signal rise,n_rise : std_logic; -- m1 状态机输出数据 signal fall,n_fall : std_logic; -- m1 状态机输出数据
signal output_strobe : std_logic; -- 锁存数据到输出寄存器 signal packet_good : std_logic; -- 检查数据是否有效 signal mouseyy : std_logic_vector(9 downto 0); signal clk:std_logic; --mouse clk------ signal count:integer range 0 to 62;
signal data_ready : std_logic;-- rx_read_o signal error_no_ack : std_logic; begin
process(clk_sys,reset) begin
if(reset='1')then clk<='0'; count<=0;
elsif(clk_sys'event and clk_sys='1')then if(count=62)then count<=0; clk<=NOT clk;
else count<=count+1; end if; end if; end process;
ps2_clk <= '0' when ps2_clk_hi_z='0' else 'Z'; ps2_data <= '0' when ps2_data_hi_z='0' else 'Z'; ------------------------------------
--检测 ps2clk 上升沿和下降沿 ------------------------------------
detect_ps2clkfall : process(clk,reset,ps2_clk) begin
if reset='1' then fallsig <= \"000\";
elsif clk'event and clk='1' then fallsig(0) <= ps2_clk; fallsig(1) <= fallsig(0); fallsig(2) <= fallsig(1); end if;
end process;
fall <= '1' when fallsig=\"110\" else '0';
detect_ps2clkrise : process(clk,reset,ps2_clk) begin
if reset='1' then risesig <= \"000\";
elsif clk'event and clk='1' then
risesig(0) <= ps2_clk; risesig(1) <= risesig(0); risesig(2) <= risesig(1); end if;
end process;
rise <= '1' when risesig=\"001\" else '0'; ------------------m2 状态
m2statech: process (reset, clk) begin
if (reset='1') then
m2_state <= m2_reset;
elsif (clk'event and clk='1') then m2_state <= m2_next_state; end if;
end process;
--m2 状态传输逻辑 m2statetr: process (m2_state, fall,rise,watchdog_timer_done,bitcount,ps2_data,packet_good) begin
-- 输出信号的缺省值 ps2_clk_hi_z <= '1'; ps2_data_hi_z <= '1'; error_no_ack <= '0'; output_strobe <= '0'; case m2_state is
when m2_reset => -- 复位后向鼠标发送命令字 m2_next_state <= m2_hold_clk_l; when m2_wait => if (fall='1') then
m2_next_state <= m2_gather; else
m2_next_state <= m2_wait; end if;
when m2_gather =>
if ((watchdog_timer_done='1') and (bitcount=TOTAL_BITS))then m2_next_state <= m2_verify; else
m2_next_state <= m2_gather; end if;
when m2_verify =>
--if (bitcount < TOTAL_BITS) then --替换 \" packet_good='1' \" --m2_next_state <= m2_wait; --else
m2_next_state <= m2_use;
q,
--end if;
when m2_use =>
output_strobe <= '1';
m2_next_state <= m2_wait;
-- 用状态机的 9 个状态实现命令字传输,使鼠标进入\"streaming\"模式, -- 并等待鼠标正确应答 when m2_hold_clk_l =>
ps2_clk_hi_z <= '0'; -- 启动看门狗! if (watchdog_timer_done='1') then m2_next_state <= m2_data_low_1; else
m2_next_state <= m2_hold_clk_l; end if;
when m2_data_low_1 =>
ps2_data_hi_z <= '0'; -- 数据位 开始位, d[0] and d[1] if (fall='1' and (bitcount = 2)) then m2_next_state <= m2_data_high_1; else
m2_next_state <= m2_data_low_1; end if;
when m2_data_high_1 =>
ps2_data_hi_z <= '1'; -- 数据位 d[2] if (fall='1' and (bitcount = 3)) then m2_next_state <= m2_data_low_2; else
m2_next_state <= m2_data_high_1; end if;
when m2_data_low_2 =>
ps2_data_hi_z <= '0'; -- 数据位 d[3] if (fall='1' and (bitcount = 4)) then m2_next_state <= m2_data_high_2; else
m2_next_state <= m2_data_low_2; end if;
when m2_data_high_2 =>
ps2_data_hi_z <= '1'; -- 数据位 d[4],d[5],d[6],d[7] if (fall='1' and (bitcount = 8)) then m2_next_state <= m2_data_low_3; else
m2_next_state <= m2_data_high_2; end if;
when m2_data_low_3 =>
ps2_data_hi_z <= '0'; -- 奇偶校验位 if (fall='1') then
m2_next_state <= m2_data_high_3; else
m2_next_state <= m2_data_low_3; end if;
when m2_data_high_3 =>
ps2_data_hi_z <= '1'; -- 允许鼠标拉成低电平(ACK 脉冲) if (fall='1' and (ps2_data='1')) then m2_next_state <= m2_error_no_ack; elsif (fall='1' and (ps2_data='0')) then m2_next_state <= m2_await_response; else
m2_next_state <= m2_data_high_3; end if;
when m2_error_no_ack => error_no_ack <= '1';
m2_next_state <= m2_error_no_ack;
-- 为了鼠标正确进入\"streaming\"模式,状态极必须等待足够长的时间, -- 确保鼠标正确应答 0xFA。 when m2_await_response => --if (bitcount = 22) then m2_next_state <= m2_verify; --else
-- m2_next_state <= m2_await_response; --end if;
when others => m2_next_state <= m2_wait; end case;
end process;-----------------------------m2 状态结束 --位计数器
bitcoun: process (reset, clk) begin
if (reset='1') then
bitcount <= (others=>'0'); -- normal reset elsif (clk'event and clk='1') then if (fall='1') then
bitcount <= bitcount + 1;
elsif (watchdog_timer_done='1') then
bitcount <= (others=>'0'); -- rx watchdog timer reset end if; end if;
end process;
-- 数据移位寄存器
dataseq: process (reset, clk) begin
if (reset='1') then q <= (others=>'0');
elsif (clk'event and clk='1') then if (fall='1') then
q <= ps2_data & q(TOTAL_BITS-1 downto 1); end if; end if;
end process;
-- 看门狗时间计数器
watchcount: process (reset,rise,fall, clk) begin
if ((reset='1') or (rise='1') or (fall='1')) then watchdog_timer_count <= (others=>'0'); elsif (clk'event and clk='1') then if (watchdog_timer_done='0') then
watchdog_timer_count <= watchdog_timer_count + 1; end if; end if;
end process;
watchdog_timer_done <= '1' when (watchdog_timer_count=WATCHDOG-1) else '0'; -- 接收数据包有效标志 packet_good <= '1';
-- 输出数据
outdata: process (reset, clk) begin
if (reset='1') then left_button <= '0'; right_button <= '0';
--x_increment <= (others=>'0'); --y_increment <= (others=>'0'); elsif (clk'event and clk='1') then if (output_strobe='1') then left_button <= q(1); right_button <= q(2);
--x_increment <= '0' & q(19 downto 12);
mouseyy <= not (q(6) & q(6) & q(30 downto 23)) + \"1\"; end if; end if;
end process;
cordinatex: process (reset,clk) begin
if (reset='1') then
mousex <= \"0000001010\";--\"0101000000\"; -- 320 elsif (clk'event and clk='1') then
if (output_strobe='1') then
if ((mousex = \"1001111111\" and q(5)='0'))or((mousex = \"0000000000\" and q(5)='1')) then mousex <= mousex; else
mousex <= mousex + (q(5) & q(5) & q(19 downto 12));--q(5):xsign q(6):ysign end if; end if; end if;
end process;
cordinatey: process (reset, clk) begin
if (reset='1') then
mousey <= \"0000001010\";--\"0011110000\"; -- 240 elsif (clk'event and clk='1') then if (output_strobe='1') then
if ((mousey = \"1110111111\" and q(6)='1'))or((mousey = \"0000000000\" and q(6)='0'))then mousey<=mousey; else
mousey <= mousey + mouseyy; --(q(6) & q(6) & q(30 downto 23)); end if; end if; end if;
end process;
--mousey <= \"1001010101\"-mouseyy; data_ready <= output_strobe; end Behavioral;
--------------------------------------------------------------------------------------------
--------------------vga协议------------------------------------------------ module VGA_protocol #( parameter HSTS = 800, //all hsync times HSTDISP = 640, //hsync display times HSTPW = 96, //hsync pluse width times HSTFP = 16, //hsync front pluse times HSTBP = 48, //hsync back pluse times VSTS = 521, //all vsync pluse times VSTDISP = 480, //vsync display pluse times VSTPW = 2, //vsync pluse times VSTFP = 10, //vsync front pluse times VSTBP = 29, //vsync back pluse times width_x = 10, //display x coordinate width width_y = 10 //display y coordinate width )
( video_clk, rst_n, //ram interface video_rgb, video_x, //point coordinate video_y, //VGA transfer video_hsync, video_vsync, video_en, video_r, video_g, video_b );
input video_clk; //25M input rst_n; //reset
//ram 接口
input [7:0] video_rgb;
output [width_x-1:0] video_x; output [width_y-1:0] video_y;
//fpga与vga接口信息
output video_hsync; //行同步信号 output video_vsync;//场同步信号 output video_en; //输出使能 output [2:0] video_r; output [2:0] video_g; output [1:0] video_b;
//coordinate count reg [width_x-1:0] x_cnt; reg [width_y-1:0] y_cnt;
wire [width_x-1:0] x_cnt_pre; wire [width_y-1:0] y_cnt_pre;
//generate x_cnt
always@(posedge video_clk or negedge rst_n) if(!rst_n) x_cnt<={width_x{1'b0}}; else x_cnt<=x_cnt_pre;
assign x_cnt_pre=(x_cnt==HSTS-1'b1)?{width_x{1'b0}}:(x_cnt+1'b1);
//generate cnt_y
always@(posedge video_clk or negedge rst_n) if(!rst_n) y_cnt<={width_y{1'b0}}; else y_cnt<=y_cnt_pre;
assign
y_cnt_pre=(y_cnt==VSTS-1'b1)?{width_y{1'b0}}:((x_cnt==HSTS-1'b1)?(y_cnt+1'b1):y_cnt);
//generate hsync reg hsync_r;
wire hsync_r_pre;
always@(posedge video_clk or negedge rst_n) if(!rst_n) hsync_r<=1'b1; else hsync_r<=hsync_r_pre;
assign hsync_r_pre=(x_cnt=={width_x{1'b0}})?1'b0:((x_cnt==HSTPW)?1'b1:hsync_r); assign video_hsync=hsync_r_pre;
//generate vsync reg vsync_r;
wire vsync_r_pre;
always@(posedge video_clk or negedge rst_n) if(!rst_n) vsync_r<=1'b1; else vsync_r<=vsync_r_pre;
assign vsync_r_pre=(y_cnt=={width_y{1'b0}})?1'b0:((y_cnt==VSTPW)?1'b1:vsync_r); assign video_vsync=vsync_r;
//generate en wire video_en; wire hs_en; wire vs_en;
assign hs_en=(x_cnt>=HSTPW+HSTBP)&(x_cnt assign video_x=hs_en?(x_cnt-HSTPW-HSTBP):{width_x{1'b0}}; assign video_y=vs_en?(y_cnt-VSTPW-VSTBP):{width_y{1'b0}}; //r,g,b控制液晶屏颜色显示 assign video_r=video_en ? video_rgb[7:5]:3'b000; assign video_g=video_en ? video_rgb[4:2]:3'b000; assign video_b=video_en ? video_rgb[1:0]:2'b00; endmodule ------------------------------------------------------------------------------------------------- -----------------------vga数据处理------------------------------------------------- module vga_picture_all #( parameter pattern_x = 10'd234, pattern_y = 9'd140, pattern_width = 10'd40, pattern_high = 9'd100, frame_width = 4'd4, framecolor = 8'h00 ) ( clk, mx, my, left_button, right_button, key_1yuan, key_5yuan, key_10yuan, rst_n, vga_x, vga_y, vga_rgb ); input left_button; input right_button; input clk; input rst_n; input [9:0]vga_x; input [9:0]vga_y; input key_1yuan; input key_5yuan; input key_10yuan; input [9:0]mx; input [9:0]my; //wire en_frame1_1; //wire en_frame2_2; //wire en_frame3_3; //wire en_frame4_4; wire en_change_out; wire en_buy_out; output [7:0]vga_rgb; wire [11:0] addr1; wire [11:0] addr2; wire [11:0] addr3; wire [11:0] addr4; wire en1; wire en2; wire en3; wire en4; wire en; wire [7:0] rgb1; wire [7:0] rgb2; wire [7:0] rgb3; wire [7:0] rgb4; wire [9:0] yuanaddr1; wire [9:0] yuanaddr2; wire [9:0] yuanaddr3; wire [9:0] yuanaddr4; wire yuanen1; wire yuanen2; wire yuanen3; wire yuanen4; wire yuanrgb1; wire yuanrgb2; wire yuanrgb3; wire yuanrgb4; wire [7:0] framergb1; wire [7:0] framergb2; wire [7:0] framergb3; wire [7:0] framergb4; wire [7:0] rgb; wire yuanrgb; wire [7:0] framergb; wire [7:0]vga_rgb_pre; wire [7:0]mousergb; wire en_frame1; wire en_frame2; wire en_frame3; wire en_frame4; wire en_frame1_1; wire en_frame2_2; wire en_frame3_3; wire en_frame4_4; reg[7:0]framergb1_1; reg [7:0]framergb2_2; reg [7:0]framergb3_3; reg [7:0]framergb4_4; wire clk_10ms; wire [3:0]all_shi; wire [3:0]all_ge; wire [3:0]all_fen; wire en_buy; wire [9:0] addr_buy; wire buy_rgb; wire en_change; wire [9:0] addr_change; wire change_rgb; //wire [7:0]framergb1_1; //wire [7:0]framergb2_2; //wire [7:0]framergb3_3; //wire [7:0]framergb4_4; wire [7:0]display_vga1; wire [7:0]display_vga2; wire [7:0]display_vga3; wire [7:0]display_vga4; wire [7:0]display_vga5; wire [7:0]display_vga6; wire [3:0]buy_shi; wire [3:0]buy_ge; wire [3:0]buy_fen; wire buy_rgb_pre; wire change_rgb_pre; wire en_buy_zero; wire en_change_zero; assign rgb = en1 ? rgb1 : en2 ? rgb2 : en3 ? rgb3 : en4 ? rgb4 : 8'hff; assign framergb = en_frame1 ? framergb1_1: en_frame2 ? framergb2_2: en_frame3 ? framergb3_3: en_frame4 ? framergb4_4:8'hff; assign buy_rgb_pre = en_buy ? buy_rgb : 1'b1; assign change_rgb_pre = en_change ? change_rgb : 1'b1; assign yuanrgb = yuanen1 ? yuanrgb1 : yuanen2 ? yuanrgb2 : yuanen3 ? yuanrgb3 : yuanen4 ? yuanrgb4 : 1'b1; assign vga_rgb_pre = rgb & framergb & {8{yuanrgb}} & {8{buy_rgb_pre}} & {8{change_rgb_pre}} & display_vga1 & display_vga2 & display_vga3 & display_vga4 & display_vga5 & display_vga6; assign vga_rgb = en ? mousergb : vga_rgb_pre; assign en_frame1_1=(mx>=pattern_x && (mx<=pattern_x+pattern_width) && my>=pattern_y && (my<=pattern_y+pattern_high)) ? 1'b1:1'b0; assign en_frame2_2=((mx>=10'd282)&& (mx<=10'd322) && my>=pattern_y && (my<=pattern_y+pattern_high)) ? 1'b1:1'b0; assign en_frame3_3=((mx>=pattern_x + 2 * (pattern_width + 2*frame_width)) && (mx<=pattern_x + 2 * (pattern_width + 2*frame_width)+pattern_width) && my>=pattern_y && (my<=pattern_y+pattern_high)) ? 1'b1:1'b0; assign en_frame4_4=((mx>=pattern_x + 3 * (pattern_width + 2*frame_width)) && (mx<=pattern_x + 3 * (pattern_width + 2*frame_width)+pattern_width) && my>=pattern_y && (my<=pattern_y+pattern_high)) ? 1'b1:1'b0; // //assign framergb1_1=en_frame1_1 ? (framergb1|8'he0):framergb1; //assign framergb2_2=en_frame2_2 ? (framergb2|8'he0):framergb2; //assign framergb3_3=en_frame3_3 ? (framergb3|8'he0):framergb3; //assign framergb4_4=en_frame4_4 ? (framergb4|8'he0):framergb4; // always@(posedge clk or negedge rst_n) begin if(!rst_n) framergb1_1<=8'hff; else if(en_frame1_1==1) framergb1_1<=8'he0; else framergb1_1<=framergb1; end // always@(posedge clk or negedge rst_n) begin if(!rst_n) framergb2_2<=8'hff; else if(en_frame2_2==1) framergb2_2<=8'he0; else framergb2_2<=framergb2; end always@(posedge clk or negedge rst_n) begin if(!rst_n) framergb3_3<=8'hff; else if(en_frame3_3==1) framergb3_3<=8'he0; else framergb3_3<=framergb3; end always@(posedge clk or negedge rst_n) begin if(!rst_n) framergb4_4<=8'hff; else if(en_frame4_4==1) framergb4_4<=8'he0; else framergb4_4<=framergb4; end div #(.counter(32'd125000)) div_10ms ( .inclk(clk), .rst_n(rst_n), .outclk(clk_10ms) ); //按键 KEY key( .clk_10ms(clk_10ms), .rst_n(rst_n), .key_1yuan(key_1yuan), .key_5yuan(key_5yuan), .key_10yuan(key_10yuan), .en_buy_zero(en_buy_zero), .en_change_zero(en_change_zero), .buy_fen(buy_fen), .buy_ge(buy_ge), .buy_shi(buy_shi), .all_shi(all_shi), .all_ge(all_ge), .all_fen(all_fen) ); //鼠标按键 mouse_key mouse_key( .clk_10ms(clk_10ms), .rst_n(rst_n), .left_button(left_button), .right_button(right_button), .en_frame1_1(en_frame1_1), .en_frame2_2(en_frame2_2), .en_frame3_3(en_frame3_3), .en_frame4_4(en_frame4_4), .en_buy_in(en_buy_out), .en_change_in(en_change_out), .en_buy_zero(en_buy_zero), .en_change_zero(en_change_zero), .buy_shi(buy_shi), .buy_ge(buy_ge), .buy_fen(buy_fen) ); //鼠标方块 triangle u1triangle ( .clk(clk), .rst_n(rst_n), .vga_x(vga_x), .vga_y(vga_y), .dian_x(mx), .dian_y(my), .en(en), .vga_rgb(mousergb) ); //********************************************************************************* //vga三位数码管 VGASegDisplay VGASegDisplay #( #( .LeftTopx(10'd234), .LeftTopy(10'd300) ) dosplay_1 ( .data(buy_shi), .dp(1'b0), .vga_x(vga_x), .vga_y(vga_y), .vga_rgb(display_vga1) ); .LeftTopx(10'd259), .LeftTopy(10'd300) ) dosplay_2 ( .data(buy_ge), .dp(1'b1), .vga_x(vga_x), .vga_y(vga_y), .vga_rgb(display_vga2) ); VGASegDisplay #( .LeftTopx(10'd290), .LeftTopy(10'd300) ) dosplay_3 ( .data(buy_fen), .dp(1'b0), .vga_x(vga_x), .vga_y(vga_y), .vga_rgb(display_vga3) ); //**************************************************************************************** //另一个三位数码管 VGASegDisplay VGASegDisplay #( #( .LeftTopx(10'd234), .LeftTopy(10'd380) ) dosplay_4 ( .data(all_shi), .dp(1'b0), .vga_x(vga_x), .vga_y(vga_y), .vga_rgb(display_vga4) ); .LeftTopx(10'd259), .LeftTopy(10'd380) ) dosplay_5 ( .data(all_ge), .dp(1'b1), .vga_x(vga_x), .vga_y(vga_y), .vga_rgb(display_vga5) ); VGASegDisplay #( .LeftTopx(10'd290), .LeftTopy(10'd380) ) dosplay_6 ( .data(all_fen), .dp(1'b0), .vga_x(vga_x), .vga_y(vga_y), .vga_rgb(display_vga6) ); //********************************************************************************************** assign en_buy_out = (mx>=350 & mx<=390 & my>=310 & my<=330) ? 1'b1 : 1'b0; read_module #( .pattern_x(10'd350), .pattern_y(10'd310), .pattern_width(10'd40), .pattern_high(9'd20) ) buyaddr ( .clk(clk), .rst_n(rst_n), .vga_x(vga_x), .vga_y(vga_y), .en(en_buy), .addr(addr_buy) ); buy buy ( .clka(clk), // input clka .addra(addr_buy), // input [8 : 0] addra .douta(buy_rgb) // output [0 : 0] douta ); assign en_change_out = (mx>=350 & mx<=390 & my>=390 & my<=410) ? 1'b1 : 1'b0; read_module #( .pattern_x(10'd350), .pattern_y(10'd390), .pattern_width(10'd40), .pattern_high(9'd20) ) changeaddr ( .clk(clk), .rst_n(rst_n), .vga_x(vga_x), .vga_y(vga_y), .en(en_change), .addr(addr_change) ); change change ( .clka(clk), // input clka .addra(addr_change), // input [8 : 0] addra .douta(change_rgb) // output [0 : 0] douta ); //茉莉蜜茶 //取地址 read_module #( .pattern_x(pattern_x), .pattern_y(pattern_y) ) molimicha_addr ( .clk(clk), .rst_n(rst_n), .vga_x(vga_x), .vga_y(vga_y), .en(en1), .addr(addr1) ); molimicha1 molimicha( .clka(clk), .addra(addr1), .douta(rgb1) ); frame #( .x_lengthframe(pattern_width + 2 * frame_width), .y_lengthframe(pattern_high + 2 * frame_width), .x_frame(pattern_x - frame_width), .y_frame(pattern_y - frame_width), .widthframe(frame_width), .framecolor(8'h00) ) rommolichaframe1 ( .clk(clk), .rst_n(rst_n), .vga_x(vga_x), .vga_y(vga_y), .en(en_frame1), .frame_rgb(framergb1) ); read_module #( .pattern_x(pattern_x), .pattern_y(pattern_y + pattern_high + frame_width), .pattern_high(9'd20) ) yuan45addr ( .clk(clk), .rst_n(rst_n), .vga_x(vga_x), .vga_y(vga_y), .en(yuanen1), .addr(yuanaddr1) ); yuan4_5 yuan4_5( .clka(clk), // input clka .addra(yuanaddr1), // input [9 : 0] addra .douta(yuanrgb1) // output [7 : 0] douta ); //------------------------------------------------------------------------------------------------------------------- //冰红茶 read_module #( .pattern_x(10'd282), .pattern_y(pattern_y) ) binghongchaaddr ( .clk(clk), .rst_n(rst_n), .vga_x(vga_x), .vga_y(vga_y), .en(en2), .addr(addr2) ); //取图片 binghongcha binghongcha ( .clka(clk), // input clka .addra(addr2), // input [11 : 0] addra .douta(rgb2) // output [7 : 0] douta ); //方框 frame #( .x_lengthframe(pattern_width + 2 * frame_width), .y_lengthframe(pattern_high + 2 * frame_width), .x_frame(10'd278), .y_frame(pattern_y - frame_width), .widthframe(frame_width), .framecolor(framecolor) ) binghongchaframe2 ( .clk(clk), .rst_n(rst_n), .vga_x(vga_x), .vga_y(vga_y), .en(en_frame2), .frame_rgb(framergb2) ); //取价格地址 read_module #( .pattern_x(10'd282), .pattern_y(pattern_y + pattern_high + frame_width), .pattern_high(9'd20) ) yuan2_5addr ( .clk(clk), .rst_n(rst_n), .vga_x(vga_x), .vga_y(vga_y), .en(yuanen2), .addr(yuanaddr2) ); //价格 yuan2_5 yuan2_5 ( .clka(clk), // input clka .addra(yuanaddr2), // input [9 : 0] addra .douta(yuanrgb2) // output [7 : 0] douta ); //---------------------------------------------------------------------------------------------------------- //芬达 //取地址 read_module #( .pattern_x(pattern_x + 2 * (pattern_width + 2*frame_width)), .pattern_y(pattern_y) ) fendaaddr ( .clk(clk), .rst_n(rst_n), .vga_x(vga_x), .vga_y(vga_y), .en(en3), .addr(addr3) ); //取图片 fenda fenda ( .clka(clk), // input clka .addra(addr3), // input [11 : 0] addra .douta(rgb3) // output [7 : 0] douta ); //方框 frame #( .x_lengthframe(pattern_width + 2 * frame_width), .y_lengthframe(pattern_high + 2 * frame_width), .x_frame(pattern_x + 2 * pattern_width + 3*frame_width), .y_frame(pattern_y - frame_width), .widthframe(frame_width), .framecolor(framecolor) ) fendaframe3 ( .clk(clk), .rst_n(rst_n), .vga_x(vga_x), .vga_y(vga_y), .en(en_frame3), ); //取价格地址 read_module #( .frame_rgb(framergb3) .pattern_x(pattern_x + 2 * (pattern_width + 2*frame_width)), .pattern_y(pattern_y + pattern_high + frame_width), .pattern_high(9'd20) ) yuan15addr ( .clk(clk), .rst_n(rst_n), .vga_x(vga_x), .vga_y(vga_y), .en(yuanen3), .addr(yuanaddr3) ); //价格 yuan1point5 yuan1_5 ( .clka(clk), // input clka .addra(yuanaddr3), // input [9 : 0] addra .douta(yuanrgb3) // output [7 : 0] douta ); //-------------------------------------------------------------------------------------------------------- //水蜜桃 //取地址 read_module #( .pattern_x(pattern_x + 3 * (pattern_width + 2*frame_width)), .pattern_y(pattern_y) ) shuimitaoaddr ( .clk(clk), .rst_n(rst_n), .vga_x(vga_x), .vga_y(vga_y), .en(en4), .addr(addr4) ); //取图片 shuimitao shuimitao( .clka(clk), .addra(addr4), //方框 frame #( .douta(rgb4) ); .x_lengthframe(pattern_width + 2 * frame_width), .y_lengthframe(pattern_high + 2 * frame_width), .x_frame(pattern_x + 3 * pattern_width + 5 * frame_width), .y_frame(pattern_y - frame_width), .widthframe(frame_width), .framecolor(framecolor) ) shuimitaoframe4 ( .clk(clk), .rst_n(rst_n), .vga_x(vga_x), .vga_y(vga_y), .en(en_frame4), .frame_rgb(framergb4) ); //取价格地址 read_module #( .pattern_x(pattern_x + 3 * (pattern_width + 2*frame_width)), .pattern_y(pattern_y + pattern_high + frame_width), .pattern_high(9'd20) ) yuan1addr ( .clk(clk), .rst_n(rst_n), .vga_x(vga_x), .vga_y(vga_y), .en(yuanen4), .addr(yuanaddr4) ); //价格 yuan1 yuan1( .clka(clk), .addra(yuanaddr4), .douta(yuanrgb4) ); endmodule --------------------------------------------------------------- --------------------------------------按键加数据处理模快 -------------------------------------------------------- module KEY( input clk_10ms, input rst_n, input key_1yuan, input key_5yuan, input key_10yuan, input en_buy_zero, input en_change_zero, input [3:0] buy_fen, input [3:0] buy_ge, input [3:0] buy_shi, output reg [3:0]all_shi, output reg [3:0]all_ge, output reg [3:0]all_fen ); reg key_1yuan_Q, key_1yuan_2Q, key_1yuan_3Q; reg key_5yuan_Q, key_5yuan_2Q, key_5yuan_3Q; reg key_10yuan_Q, key_10yuan_2Q, key_10yuan_3Q; wire en_1yuan; wire en_5yuan; wire en_10yuan; wire [3:0]all_shi_pre; wire [3:0]all_ge_pre; wire [3:0]all_fen_pre; always @(posedge clk_10ms or negedge rst_n) begin if(!rst_n) begin key_1yuan_Q <= 1'b0; key_1yuan_2Q <= 1'b0; key_1yuan_3Q <= 1'b0; end else begin key_1yuan_Q <= key_1yuan; key_1yuan_2Q <= key_1yuan_Q; key_1yuan_3Q <= key_1yuan_2Q; end end assign en_1yuan = key_1yuan_Q & key_1yuan_2Q & (~key_1yuan_3Q); always @(posedge clk_10ms or negedge rst_n) begin if(!rst_n) begin key_5yuan_Q <= 1'b0; key_5yuan_2Q <= 1'b0; key_5yuan_3Q <= 1'b0; end else begin key_5yuan_Q <= key_5yuan; key_5yuan_2Q <= key_5yuan_Q; key_5yuan_3Q <= key_5yuan_2Q; end end assign en_5yuan = key_5yuan_Q & key_5yuan_2Q & (~key_5yuan_3Q); always @(posedge clk_10ms or negedge rst_n) begin if(!rst_n) begin key_10yuan_Q <= 1'b0; key_10yuan_2Q <= 1'b0; key_10yuan_3Q <= 1'b0; end else begin key_10yuan_Q <= key_10yuan; key_10yuan_2Q <= key_10yuan_Q; key_10yuan_3Q <= key_10yuan_2Q; end end assign en_10yuan = key_10yuan_Q & key_10yuan_2Q & (~key_10yuan_3Q); always @(posedge clk_10ms or negedge rst_n) if(!rst_n) all_ge<=0; else all_ge<=all_ge_pre; always @(posedge clk_10ms or negedge rst_n) if(!rst_n) all_shi<=0; else all_shi<=all_shi_pre; always @(posedge clk_10ms or negedge rst_n) if(!rst_n) all_fen<=0; else all_fen<=all_fen_pre; assign all_ge_pre = en_change_zero ? 0:( all_shi>=10 ? 10: (en_1yuan ? all_ge + 1 : en_5yuan ? all_ge + 5 : (all_ge==10) ? 0 : (all_ge==11) ? 1 : (all_ge==12) ? 2 : (all_ge==13) ? 3 : en_buy_zero ? (buy_fen>all_fen ? ((all_ge>buy_ge)? (all_ge-buy_ge-1):(10-buy_ge+all_ge-1)):((all_ge>=buy_ge)? (all_ge-buy_ge):(10-buy_ge+all_ge))): all_shi==10 ? 10 :all_ge)); assign all_shi_pre =en_change_zero ? 0: ( all_shi>=10 ? 10: ((all_ge==10) ? all_shi+1 : (all_ge==11) ? all_shi+1 : (all_ge==12) ? all_shi+1 : (all_ge==13) ? all_shi+1 : en_10yuan ? all_shi + 1 : en_buy_zero ? ((buy_fen+10*buy_ge>10*all_ge+all_fen) ? ((all_shi>buy_shi)? (all_shi-buy_shi-1):10):((all_shi>=buy_shi) ? (all_shi-buy_shi) : 10)):all_shi)); assign all_fen_pre = en_change_zero ? 0 : all_shi==10 ? 10 : en_buy_zero ? (buy_fen==5 ? buy_fen-all_fen : all_fen) :all_fen; endmodule --------------------------鼠标按键加数据处理模块--------------------- module mouse_key( input clk_10ms, input rst_n, input left_button, input right_button, input en_frame1_1, input en_frame2_2, input en_frame3_3, input en_frame4_4, input en_buy_in, input en_change_in, output en_buy_zero, output en_change_zero, output reg [3:0]buy_shi, output reg [3:0]buy_ge, ); reg left_button_Q, left_button_2Q, left_button_3Q; reg right_button_Q, right_button_2Q, right_button_3Q; output reg [3:0]buy_fen wire en_left; wire en_right; wire [3:0]buy_shi_pre; wire [3:0]buy_ge_pre; wire [3:0]buy_fen_pre; reg [3:0]counter_45; reg [3:0]counter_25; reg [3:0]counter_15; reg [3:0]counter_10; wire [3:0]counter_45_pre; wire [3:0]counter_25_pre; wire [3:0]counter_15_pre; wire [3:0]counter_10_pre; always @(posedge clk_10ms or negedge rst_n) begin if(!rst_n) begin left_button_Q <= 1'b0; left_button_2Q <= 1'b0; left_button_3Q <= 1'b0; end else begin left_button_Q <= left_button; left_button_2Q <= left_button_Q; left_button_3Q <= left_button_2Q; end end assign en_left = left_button_Q & (~left_button_2Q) & (~left_button_3Q); always @(posedge clk_10ms or negedge rst_n) begin if(!rst_n) begin right_button_Q <= 1'b0; right_button_2Q <= 1'b0; right_button_3Q <= 1'b0; end else begin right_button_Q <= right_button; right_button_2Q <= right_button_Q; right_button_3Q <= right_button_2Q; end end assign en_right = right_button_Q & right_button_2Q & (~right_button_3Q); assign en_45_add = (en_left & en_frame1_1) ? 1'b1 : 1'b0; assign en_25_add = (en_left & en_frame2_2) ? 1'b1 : 1'b0; assign en_15_add = (en_left & en_frame3_3) ? 1'b1 : 1'b0; assign en_10_add = (en_left & en_frame4_4) ? 1'b1 : 1'b0; assign en_45_reduce = (en_right & en_frame1_1) ? 1'b1 : 1'b0; assign en_25_reduce = (en_right & en_frame2_2) ? 1'b1 : 1'b0; assign en_15_reduce = (en_right & en_frame3_3) ? 1'b1 : 1'b0; assign en_10_reduce = (en_right & en_frame4_4) ? 1'b1 : 1'b0; assign en_buy_zero = (en_left & en_buy_in ) ? 1'b1 : 1'b0; assign en_change_zero=(en_left & en_change_in)? 1'b1 : 1'b0; //--------------------------------------------------------------------------- always @(posedge clk_10ms or negedge rst_n) if(!rst_n) buy_ge<=0; else buy_ge<=buy_ge_pre; always @(posedge clk_10ms or negedge rst_n) if(!rst_n) buy_shi<=0; else buy_shi<=buy_shi_pre; always @(posedge clk_10ms or negedge rst_n) if(!rst_n) buy_fen<=0; else buy_fen<=buy_fen_pre; always @(posedge clk_10ms or negedge rst_n) if(!rst_n) counter_45<=0; else counter_45<=counter_45_pre; always @(posedge clk_10ms or negedge rst_n) if(!rst_n) counter_25<=0; else counter_25<=counter_25_pre; always @(posedge clk_10ms or negedge rst_n) if(!rst_n) counter_15<=0; else counter_15<=counter_15_pre; always @(posedge clk_10ms or negedge rst_n) if(!rst_n) counter_10<=0; else counter_10<=counter_10_pre; assign counter_10_pre=en_buy_zero ? 0: en_10_add ? counter_10+1: counter_10>0 ? (en_10_reduce ? counter_10-1:counter_10):counter_10; assign counter_15_pre=en_buy_zero ? 0: en_15_add ? counter_15+1: counter_15>0 ? (en_15_reduce ? counter_15-1:counter_15):counter_15; assign counter_25_pre=en_buy_zero ? 0: en_25_add ? counter_25+1: counter_25>0 ? (en_25_reduce ? counter_25-1:counter_25):counter_25; assign counter_45_pre=en_buy_zero ? 0: en_45_add ? counter_45+1: counter_45>0 ? (en_45_reduce ? counter_45-1:counter_45):counter_45; assign buy_fen_pre = en_buy_zero ? 0 : (buy_shi>=10 ? 10: (en_45_add ? buy_fen+5 : en_25_add ? buy_fen+5 : en_15_add ? buy_fen+5 : (((en_45_reduce&counter_45>0) | (en_25_reduce&counter_25>0) |(en_15_reduce&counter_15>0)) & buy_fen==0) ? 5: (((en_45_reduce&counter_45>0) | (en_25_reduce&counter_25>0) |(en_15_reduce&counter_15>0)) & buy_fen==5) ? 0: (buy_fen==10) ? 0 : buy_fen)); assign buy_ge_pre = en_buy_zero ? 0 : (buy_shi>=10 ? 10: (en_45_add ? ((buy_fen==10 | buy_fen==5) ? buy_ge+5:buy_ge+4) : en_25_add ? ((buy_fen==10 | buy_fen==5) ? buy_ge+3:buy_ge+2) : en_15_add ? ((buy_fen==10 | buy_fen==5) ? buy_ge+2:buy_ge+1) : en_10_add ? (buy_fen==10 ? buy_ge+2:buy_ge+1) : (en_45_reduce&counter_45>0) ? (buy_ge==0 ? (buy_fen==0 ? 5:6):(buy_fen==0 ? (buy_ge>=5 ? buy_ge-5 : 5+buy_ge):(buy_ge>=4 ? buy_ge-4 : 10-(4-buy_ge)))): (en_25_reduce&counter_25>0) ? (buy_ge==0 ? (buy_fen==0 ? 7:8):(buy_fen==0 ? (buy_ge>=3 ? buy_ge-3 : 10-(3-buy_ge)):(buy_ge>=2 ? buy_ge-2 : 10-(2-buy_ge)))): (en_15_reduce&counter_15>0) ? (buy_ge==0 ? (buy_fen==0 ? 8:9):(buy_fen==0 ? (buy_ge>=2 ? buy_ge-2 : 2-buy_ge):buy_ge-1)): (en_10_reduce&counter_10>0) ? (buy_ge==0 ? 9:buy_ge-1): (buy_ge==10) ? 0 : (buy_ge==11) ? 1 : (buy_ge==13) ? 3 : (buy_ge==14) ? 4 : (buy_ge==12) ? 2 assign buy_shi_pre = en_buy_zero ? 0 : :buy_ge)); (buy_shi>=10 ? 10: ((buy_ge==10) ? buy_shi+1 : (buy_ge==11) ? buy_shi+1 : (buy_ge==12) ? buy_shi+1 : (buy_ge==14) ? buy_shi+1 : (buy_ge==13) ? buy_shi+1 : ((en_45_reduce&counter_45>0) & buy_ge<=4) ? (buy_ge==4 ? (buy_fen==0 ? buy_shi-1:buy_shi):buy_shi-1): ((en_25_reduce&counter_25>0) & buy_ge<=2) ? (buy_ge==2 ? (buy_fen==0 ? buy_shi-1:buy_shi):buy_shi-1): ((en_15_reduce&counter_15>0) & buy_ge<=1) ? (buy_ge==1 ? (buy_fen==0 ? buy_shi-1:buy_shi):buy_shi-1): ((en_10_reduce&counter_10>0) & buy_ge==0) ? buy_shi-1 : buy_shi)); Endmodule --------------------------地址生成模块--------------------------- module read_module#( parameter pattern_x=10'd100, parameter pattern_y=9'd100, parameter pattern_width=10'd40, parameter pattern_high=9'd100 ) (clk,rst_n,vga_x,vga_y,en,addr); input clk; input rst_n; input [9:0] vga_x; input [9:0] vga_y; output [11:0] addr; output reg en; wire en_pre; assign en_pre = (vga_x >= pattern_x) && (vga_x < pattern_x + pattern_width) && (vga_y >= pattern_y) && (vga_y < pattern_y + pattern_high); assign addr = (vga_y - pattern_y) * pattern_width + vga_x - pattern_x; always@(posedge clk or negedge rst_n) if (!rst_n) en<=1'b0; else en<=en_pre; endmodule -----------------------图片边框模块------------------------------- module frame #( ) ( clk, rst_n, vga_x, vga_y, en, parameter width_x = 4'd10, width_y = 4'd10, x_lengthframe = 9'd300, y_lengthframe = 9'd120, x_frame = 10'd0, y_frame = 10'd0, widthframe = 4'd10, framecolor = 8'b111_111_00 ); frame_rgb input clk; input rst_n; input [width_x-1:0] vga_x; input [width_y-1:0] vga_y; output [7:0] frame_rgb; output en; wire en_frame; wire en_frameleft; wire en_frameright; wire en_frameup; wire en_framedown; wire [7:0] frame_rgb; assign en_frameleft = (vga_x >= x_frame) && (vga_x < x_frame + //the enable of the left frame widthframe) && (vga_y >= y_frame) && (vga_y < y_frame + y_lengthframe); assign en_frameright = (vga_x >= x_frame + x_lengthframe - widthframe) && (vga_x < x_frame + x_lengthframe) && (vga_y >= y_frame) && (vga_y < y_frame + y_lengthframe); assign en_frameup = (vga_y >= y_frame) && (vga_y < y_frame + widthframe) && (vga_x >= x_frame) && (vga_x < x_frame + x_lengthframe); assign en_framedown = (vga_y >= y_frame + y_lengthframe - widthframe) && (vga_y < y_frame + y_lengthframe) && (vga_x >= x_frame) && (vga_x < x_frame + x_lengthframe); assign en_frame = en_frameleft | en_frameright | en_frameup | en_framedown; assign frame_rgb = en_frame ? framecolor : 8'b111_111_11; assign en=en_frame; endmodule ---------------------存图片的rom------------------------------- 3、将所编写的代码进行综合,综合无误后对代码进行功能仿真。仿真结果图与仿真分析如下。 以下是部分模块的仿真的波形图 仿真出来波形一切正常 4、进行完功能仿真验证代码无误后,进行管脚分配,编写ucf文件。ucf文件如下。 NET \"clk\" LOC = B8; NET \"rst_p\" LOC = B18; NET \"vsync\" LOC = U3; NET \"hsync\" LOC = T4; NET \"video_b<0>\" LOC = U5; NET \"video_b<1>\" LOC = U4; NET \"video_g<0>\" LOC = N8; NET \"video_g<1>\" LOC = P8; NET \"video_g<2>\" LOC = P6; NET \"video_r<0>\" LOC = R9; NET \"video_r<1>\" LOC = T8; NET \"video_r<2>\" LOC = R8; NET \"ps2clk\" LOC = R12; NET \"ps2data\" LOC = P11; #NET \"led<0>\" LOC = J14; #NET \"led<1>\" LOC = J15; NET \"key_1yuan\" LOC = D18; NET \"key_5yuan\" LOC = E18; NET \"key_10yuan\" LOC = H13; 五 、报告 资源报告: 综合后的资源报告: 布局布线后的资源报告: 布局布线后的时序报告: 6、生成bit文件,并将生成的bit文件下载到nexys2板上运行。运行结果如下。 实验结论: 所设计的自动售货机实现了想达到的效果,完美完成了本次实验。 心得体会: 此次实验查阅了大量资料,发现自己仍有许多的不足之处。但此次实验最大的收获是学会了模块化的可重构的编写程序的方法,也学会了如何调用现有的ip核。 六、分工 指导教师批阅意见: 成绩评定: 指导教师签字: 年 月 日 备注: 因篇幅问题不能全部显示,请点此查看更多更全内容