/* Name: Marstdoor.v
Function:
系统顶层文件。通过调用之后的div,motor,Maintenance模块,得到电机工作频率,实现工作模式和维护模式的切换。
Input: clk – 板载100MHz时钟信号;
rst – 复位信号, ‘reset’;
SensorSignal1 – 门内红外感应模块信号;
SensorSignal2 – 门外红外感应模块信号;
Switch – 工作模式与维护模式的切换命令信号;
MaintainDirect – 维护模式下,电机转向命令信号;
Output:SensorState1 – 门外红外感应模块信号通过LED灯显示是否感应到物体;
SensorState2 – 门内红外感应模块信号通过LED灯显示是否感应到物体;
Seg_Enable – 数码管位选使能信号;
Seg_code – 数码管段选使能信号;
OUT – 电机转动信号;
*/
module marstdoor(
input clk,
input rst,
input SensorSignal1,
input SensorSignal2,
input Switch,
input MaintainDirect,
output reg SensorState1,
output reg SensorState2,
output[7:0]seg_code,
output seg_Enable,
output reg [3:0] OUT
);
always@(posedge clk)
begin
SensorState1 <= SensorSignal1;
SensorState2 <= SensorSignal2;
End
wire clkDIV;
div div(
.clk_in(clk),
.reset_low(rst),
.clk_out(clkDIV)
);
wire [3:0]OUT1; //工作状态下的电机输出信号;
wire [3:0]OUT2; //维护状态下的电机输出信号;
motor motor( //工作模式
.clk(clkDIV),
.rst(rst),
.StepEnable(Switch),
.out(OUT1),
.flag1(SensorState1),
.flag2(SensorState2)
);
Maintenance maintenance( //维护模式
.clk(clkDIV),
.direct(MaintainDirect),
.stepenable(Switch),
.an(seg_Enable),
.seg_code(seg_code),
.out(OUT2)
);
always@(posedge clk)
if(Switch==0)
OUT<=OUT1;
else if(Switch==1)
OUT<=OUT2;
endmodule
/*
Name: Maintenance.v
Function: 维护模式;通过控制板载SW信号开关,对电机的转动进行5s检测,并将计时信号实时显示在数码管上;
Input: clk – 分频后的250Hz时钟信号;
direct – 维护模式下,控制电机转向的的SW信号;
stepenble – 正常工作模式和维护模式的转换信号;
Output: an – 数码管的位选使能信号;
seg_code – 数码管的段选使能信号,共8 bits;
out – 维护模式下电机的转动状态输出;
*/
module Maintenance(
input clk,
input direct,
input stepenable,
output reg an,
output reg[7:0]seg_code,
output reg[3:0]out
);
parameter T= 27‘d250; //计时1s;这是因为我们输入的时钟信号是分频之后的250Hz;
parameter _0 = 8‘hc0,_1 = 8‘hf9,_2 = 8‘ha4,_3 = 8‘hb0,
_4 = 8‘h99,_5 = 8‘h92;
reg[31:0]cnt; //范围:0<cnt<250;过250则记1s;
reg[4:0]cnt_num; //这是数码管显示的数字;
reg[31:0]counter; //这是电机要用的计数变量;电机要转过一定的角度;
reg[3:0]state;
//接下来的部分是将电机模块的计数和数码管的计数联系在了一起;
always@(posedge clk)
if(!stepenable) //Switch信号此时为0; 即,处于工作状态,而非维护模块
begin
cnt<=0;
cnt_num<=0;
an<=0; //未进入维护模式,数码管不使能
counter<=0;
end
else if( stepenable )
begin
an<=1;
if( direct == 1 )
begin
counter<=counter+1;
cnt<=cnt+1;
if(counter<12500) //12500/250=50;
state<=state-1;
if(cnt==T)
begin
cnt_num<=cnt_num+4‘d1;
cnt<=0;
end
if(cnt_num>=5)
begin
counter<=12500;
cnt_num<=4‘b0101;
cnt<=0;
end
end
else if(direct==0)
begin
counter<=counter-1;
if(counter>0)
begin
state<=state+1;
end
cnt<=cnt+1;
if(cnt==T)
begin
cnt_num<=cnt_num-4‘d1;
cnt<=0;
end
if(cnt_num<=0)
begin
counter<=0;
cnt_num<=4‘b0;
cnt<=0;
end
end
case( cnt_num )
4‘d0:seg_code <= ~_0;
4‘d1:seg_code <= ~_1;
4‘d2:seg_code <= ~_2;
4‘d3:seg_code <= ~_3;
4‘d4:seg_code <= ~_4;
4‘d5:seg_code <= ~_5;
default: seg_code <= 8‘hff;
endcase
case (state)
3‘b000 : out <= 4‘b0001 ;
3‘b001 : out <= 4‘b0011 ;
3‘b010 : out <= 4‘b0010 ;
3‘b011 : out <= 4‘b0110 ;
3‘b100 : out <= 4‘b0100 ;
3‘b101 : out <= 4‘b1100 ;
3‘b110 : out <= 4‘b1000 ;
3‘b111 : out <= 4‘b1001 ;
endcase
end
endmodule
/*
Name: motor.v
Function: 系统的正常工作模式。在两个红外传感器的信号作用下,控制电机的转动状态;
Input: clk –- 分频后得到的250Hz时钟信号;
rst –- 板载复位信号;
flag1 –- 红外传感器1(门外)信号;
flag2 –- 红外传感器2(门内)信号;
StepEnable – 电机使能信号,控制电机进入工作状态;
Output:out – 控制电机转速和转向的信号;
*/
module motor(
out,
clk,
flag1,
flag2,
StepEnable,
rst);
input clk;
input flag1;
input flag2;
input StepEnable;
input rst;
output[3:0] out;
reg[3:0] out;
reg[2:0] state;
reg[31:0] counter;
reg[31:0] counter_num;
reg enable;
always @(posedge clk or negedge rst)
begin
if (!rst)
begin
out <= 4‘b0;
state <= 3‘b0;
counter<=32‘b0;
counter_num<=32‘b0;
enable<=0;
end
else
begin
if (StepEnable == 1‘b0)
begin
if(enable==0)
begin
if( ( ( flag1 == 0 && flag2 == 0 ) || ( flag1 == 1 && flag2 == 0 ) || ( flag1 == 0 && flag2 == 1 ) ) && counter < 2500 )
begin
counter=counter+1;
state <= state - 3‘b001 ;
end
else
begin
if(flag1==1&&flag2==1)
begin
if(counter>2500)
counter<=2500;
enable<=1;
end
end
end
else if(enable==1)
begin
if(counter_num < 1250)
counter_num <= counter_num+1;
if( flag1 == 1 && flag2 == 1 && counter > 0 && counter_num == 1250 )
begin
counter=counter-1;
state <= state + 3‘b001 ;
end
else if((flag1==0&&flag2==0)||(flag1==1&&flag2==0)||(flag1==0&&flag2==1))
begin
if(counter<=0)
counter<=0;
enable<=0;
counter_num<=0;
end
end
case (state)
3‘b000 : out <= 4‘b0001 ;
3‘b001 : out <= 4‘b0011 ;
3‘b010 : out <= 4‘b0010 ;
3‘b011 : out <= 4‘b0110 ;
3‘b100 : out <= 4‘b0100 ;
3‘b101 : out <= 4‘b1100 ;
3‘b110 : out <= 4‘b1000 ;
3‘b111 : out <= 4‘b1001 ;
endcase
end
end
end
endmodule
/*
Name: div.v
Function: 实现分频功能。这是因为电机的工作频率在250Hz,而板载晶振时钟为100MHz;
Input: clk_in -- 板载晶振时钟(100MHz);
Reset_low – 板载复位信号(’rst’);
Output: clk_out – 分频后信号(250Hz);
*/
module div(
clk_in,
clk_out,
reset_low);
input clk_in,reset_low;
output reg clk_out;
reg [31:0] cnt;
parameter CNT_NUM = 399999; // M=100MHz/250Hz=400000, CNT_NUM=M-1;
parameter CNT_HIGH = 199999; //CNT_HIGH=M/2-1;
initial
begin
cnt = 0;
clk_out = 0;
end
always @(posedge clk_in or negedge reset_low)
begin
cnt = cnt + 1;
if(cnt <= CNT_HIGH)
begin
clk_out = 1;
end
else
begin
clk_out = 0;
if(cnt == CNT_NUM)
begin
cnt = 0;
end
end
if(!reset_low)
begin
clk_out = 0;
cnt = 0;
end
end
endmodule
原文:https://www.cnblogs.com/rongyupan/p/12662680.html