|
楼主 |
发表于 2007-12-20 10:40:42
|
显示全部楼层
抱歉,我把源码还是贴在下面比较好,谢谢!
//----------------------------------
//module name: elevator.v
//editor: yin shaofei
//function: controls the engine of elevator to rise or fall, controls the elevator_door to open or close,
// flr_slct or direct_ctrl button is been used by customers, flr_demo and direct_demo is to show
// which floor the elevator is or which direction the elevator is
//modification history:
// 07 12 19 created
//-----------------------------------------
module elevator(clk_i, rst_i, flr_slct_i, dir_slct_i,flr_demo_o, dir_demo_o, eng_ctrl_o, door_state_o, state);
input clk_i;
input rst_i; //rst is used when repairation is necessary, elevator should
//return first_floor and the door opened once, and closed to sleep
//state;
input [2:0] flr_slct_i; //[0]==slct_first_floor, [1]==slct_second_floor, [2]==slct_third_floor;
input dir_slct_i; //0==dir_fall, 1==dir_rise;
//demo_board_print
output [2:0] flr_demo_o; //001==demo_first_floor, 010==demo_second_floor, 100==demo_third_floor;
output [1:0] dir_demo_o; //00==demo_sleep, 01==demo_rise, 10==demo_fall, 11==demo_reset;
reg [2:0] flr_demo_o;
reg [1:0] dir_demo_o; //reg is used when the FSM are available
//elevator engine control output;
output [1:0] eng_ctrl_o; //00==eng_sleep; 01==eng_rise; 10==eng_fall; //reg is not available;
output door_state_o; //0==closed; 1==opened;
reg [1:0] eng_ctrl_o;
reg door_state_o;
//reg [3:0] one_flr_counter; //rising or falling time counter,4'b0111 will enable the door to open state;
//reg [3:0] two_flr_counter; //rising or falling time counter,4'b1111 will enable the door to open state;
//reg [3:0] keep_open_counter; //4'b1111 means door_open state time is used up,in load_task;
integer one_flr_counter; //rising or falling time counter,4'b0111 will enable the door to open state;
integer two_flr_counter; //rising or falling time counter,4'b1111 will enable the door to open state;
integer keep_open_counter; //4'b1111 means door_open state time is used up,in load_task;
output [3:0] state;
reg [3:0] state; //cs, ns; //FSM state definition; cs==current_state; ns==next_state;
parameter [3:0]
s_flr_1=4'b0001, //elevator is at the first floor;
s_flr_2_rise=4'b0010, //elevator==second_floor, and is rising;
s_flr_2_fall=4'b0100, //elevator==second_floor, falling is prefered firstly;
s_flr_3=4'b1000;
always @(posedge clk_i or negedge rst_i)
begin
if(!rst_i)
begin //if rst is enabled, elevator returned to first_floor;
{one_flr_counter, two_flr_counter,keep_open_counter}<=12'b0000_0000_0000;
{flr_demo_o, dir_demo_o}<=5'b001_00;
{eng_ctrl_o, door_state_o}<=3'b00_0;
state<=s_flr_1;
end
else
// cs<=ns;
//end
//always @(cs or dir_slct_i or flr_slct_i) //FSM or dir or flr select filp;
// or one_flr_counter or two_flr_counter or keep_open_counter) //reg one_floor_counter or reg two_flr_counter filp;
// or flr_demo_o or dir_demo_o)
begin
case(state)
s_flr_1: begin
{one_flr_counter, two_flr_counter,keep_open_counter}<=12'b0000_0000_0000;
// {flr_demo_o, dir_demo_o}<=5'b001_00;
// {eng_ctrl_o, door_state_o}<=3'b00_1;
load_task;
if((dir_slct_i==1)&&(flr_slct_i[1]==1)&&(flr_slct_i[0]==0)) //选择上,楼层选择2
begin
{flr_demo_o, dir_demo_o}<=5'b001_01;
{eng_ctrl_o, door_state_o}<=3'b01_0;
if(one_flr_counter==4'b0111)
state<=s_flr_2_rise;
else
one_flr_counter<=one_flr_counter+1;
end
else if((dir_slct_i==1)&&(flr_slct_i==3'b100)) //选择上,楼层选择3
begin
{flr_demo_o, dir_demo_o}<=5'b001_01;
{eng_ctrl_o, door_state_o}<=3'b01_0;
if(two_flr_counter==4'b1111)
state<=s_flr_3;
else
two_flr_counter<=two_flr_counter+1;
end
else
begin
{flr_demo_o, dir_demo_o}<=5'b001_00;
{eng_ctrl_o, door_state_o}<=3'b00_1;
state<=s_flr_1;
end
end
s_flr_2_rise: begin
{one_flr_counter, two_flr_counter,keep_open_counter}<=12'b0000_0000_0000;
// {flr_demo_o, dir_demo_o}<=5'b010_01;
// {eng_ctrl_o, door_state_o}<=3'b00_1;
load_task;
/* if(flr_slct_i[1]==1)
begin
ns<=s_flr_2_rise;
end
*/
if((dir_slct_i==1)&&(flr_slct_i==3'b100)) //选择上,楼层选择3
begin
{flr_demo_o, dir_demo_o}<=5'b010_01;
{eng_ctrl_o, door_state_o}<=3'b01_0;
if(one_flr_counter==4'b0111)
state<=s_flr_3;
else
one_flr_counter<=one_flr_counter+1;
end
else if((dir_slct_i==0)&&(flr_slct_i==3'b001)) //选择下,楼层选择1
begin
{flr_demo_o, dir_demo_o}<=5'b010_10;
{eng_ctrl_o, door_state_o}<=3'b10_0;
if(one_flr_counter==4'b0111)
state<=s_flr_1;
else
one_flr_counter<=one_flr_counter+1;
end
else
begin
{flr_demo_o, dir_demo_o}<=5'b010_01;
{eng_ctrl_o, door_state_o}<=3'b00_1;
state<=s_flr_2_rise;
end
end
s_flr_2_fall: begin
{one_flr_counter, two_flr_counter,keep_open_counter}<=12'b0000_0000_0000;
// {flr_demo_o, dir_demo_o}<=5'b010_10;
// {eng_ctrl_o, door_state_o}<=3'b00_1;
load_task;
/* if(flr_slct_i[1]==1)
begin
ns<=s_flr_2_fall;
end
*/
if((dir_slct_i==0)&&(flr_slct_i[0]==3'b001)) //选择下,楼层选择1
begin
{flr_demo_o, dir_demo_o}<=5'b010_01;
{eng_ctrl_o, door_state_o}<=3'b10_0;
if(one_flr_counter==4'b0111)
state<=s_flr_1;
else
one_flr_counter<=one_flr_counter+1;
end
else if((dir_slct_i==1)&&(flr_slct_i==3'b100)) //选择上,楼层选择3
begin
{flr_demo_o, dir_demo_o}<=5'b010_10;
{eng_ctrl_o, door_state_o}<=3'b10_0;
if(one_flr_counter==4'b0111)
state<=s_flr_3;
else
one_flr_counter<=one_flr_counter+1;
end
else
begin
{flr_demo_o, dir_demo_o}<=5'b010_10;
{eng_ctrl_o, door_state_o}<=3'b00_1;
state<=s_flr_2_fall;
end
end
s_flr_3: begin
{one_flr_counter, two_flr_counter,keep_open_counter}<=12'b0000_0000_0000;
// {flr_demo_o, dir_demo_o}<=5'b100_00;
// {eng_ctrl_o, door_state_o}<=3'b00_1;
load_task;
/* if(flr_slct_i[2]==1)
begin
ns<=s_flr_3;
end
*/
if((dir_slct_i==0)&&(flr_slct_i[1]==1)&&(flr_slct_i[2]==0)) //选择下,楼层选择2
begin
{flr_demo_o, dir_demo_o}<=5'b100_10;
{eng_ctrl_o, door_state_o}<=3'b10_0;
if(one_flr_counter==4'b0111)
state<=s_flr_2_fall;
else
one_flr_counter<=one_flr_counter+1;
end
else if((dir_slct_i==0)&&(flr_slct_i==001)) //选择下,楼层选择1
begin
{flr_demo_o, dir_demo_o}<=5'b100_10;
{eng_ctrl_o, door_state_o}<=3'b10_0;
if(two_flr_counter==4'b1111)
state<=s_flr_1;
else
two_flr_counter<=two_flr_counter+1;
end
else
begin
{flr_demo_o, dir_demo_o}<=5'b100_00;
{eng_ctrl_o, door_state_o}<=3'b00_1;
state<=s_flr_3;
end
end
default: begin
{flr_demo_o, dir_demo_o}<=5'b001_00;
{eng_ctrl_o, door_state_o}<=3'b00_0;
state<=s_flr_1;
end
endcase
end
end
task load_task;
begin
if(keep_open_counter==4'b1111)
door_state_o<=1'b0;
else
begin
keep_open_counter<=keep_open_counter+1;
door_state_o<=1'b1;
end
end
endtask
endmodule
//tb
module tb_elevator(door_state_o);
reg clk_i;
reg rst_i;
reg [2:0] flr_slct_i;
reg dir_slct_i;
wire [2:0] flr_demo_o;
wire [1:0] dir_demo_o;
wire [1:0] eng_ctrl_o;
output door_state_o;
wire [3:0] state;
elevator uut(.clk_i(clk_i),
.rst_i(rst_i),
.flr_slct_i(flr_slct_i),
.dir_slct_i(dir_slct_i),
.flr_demo_o(flr_demo_o),
.dir_demo_o(dir_demo_o),
.eng_ctrl_o(eng_ctrl_o),
.door_state_o(door_state_o),
.state(state));
initial
begin
clk_i=1'b0;
rst_i=1'b0;
flr_slct_i=3'b000;
dir_slct_i=1'b0;
end
always #5 clk_i=~clk_i;
initial
begin
#200 rst_i=1'b1;
#200 begin flr_slct_i=3'b010; dir_slct_i=1'b1; end
#200 begin flr_slct_i=3'b001; dir_slct_i=1'b0; end
#200 begin flr_slct_i=3'b110; dir_slct_i=1'b1; end
#200 begin flr_slct_i=3'b001; dir_slct_i=1'b0; end
#200 begin flr_slct_i=3'b010; dir_slct_i=1'b1; end
#200 begin flr_slct_i=3'b001; dir_slct_i=1'b1; end
#200 begin flr_slct_i=3'b110; dir_slct_i=1'b0; end
#200 begin flr_slct_i=3'b001; dir_slct_i=1'b0; end
#200 rst_i=1'b0;
#200 begin flr_slct_i=3'b010; dir_slct_i=1'b1; end
#200 begin flr_slct_i=3'b001; dir_slct_i=1'b0; end
#200 begin flr_slct_i=3'b110; dir_slct_i=1'b1; end
#200 rst_i=1'b1;
#200 begin flr_slct_i=3'b001; dir_slct_i=1'b0; end
#200 begin flr_slct_i=3'b010; dir_slct_i=1'b1; end
#200 begin flr_slct_i=3'b001; dir_slct_i=1'b1; end
#200 begin flr_slct_i=3'b100; dir_slct_i=1'b1; end
#200 begin flr_slct_i=3'b011; dir_slct_i=1'b0; end
#200 begin flr_slct_i=3'b111; dir_slct_i=1'b0; end
end
endmodule |
|