【Verilog HDL实践】汽车尾灯控制电路实现

【Verilog HDL实践】汽车尾灯控制电路实现

使用芯片:Altera Cyclone® IV EP4CE22F17C6N FPGA
开发工具:Quartus Ⅱ
开发项目:

设计一个汽车尾灯控制电路。已知汽车左右两侧各有3个尾灯,采用K0、K1进行状态控制,要求尾灯按如下规则亮灭。
(1)汽车沿直线行驶时,两侧的指示灯全灭; (KEY=2’b00)
(2)右转弯时,左侧的指示灯全灭,右侧的指示灯按000,100,010,001,000循环顺序点亮;(KEY=2’b01)
(3)左转弯时,右侧的指示灯全灭,左侧的指示灯按与右侧同样的循环顺序点亮;(KEY=2’b10)
(4)如果在直行时刹车,两侧的指示灯全亮;如果在转弯时刹车,转弯这一侧的指示灯按上述的循环顺序点亮,另一侧的指示灯全亮。(KEY=2’b11)

序列检测分析

使用状态机思想
共6种状态:

当前状态当前输入下一时刻输出
直行00直行
直行10左转
直行01右转
直行11直行时刹车
直行时刹车00直行
直行时刹车10左转
直行时刹车01右转
直行时刹车11保持
其他情况类似
代码展示
/*
模块功能:
	设计一个汽车尾灯控制电路。已知汽车左右两侧各有3个尾灯,采用K0、K1进行状态控制,要求尾灯按如下规则亮灭。
		(1)汽车沿直线行驶时,两侧的指示灯全灭; (KEY=2’b00)
		(2)右转弯时,左侧的指示灯全灭,右侧的指示灯按000,100,010,001,000循环顺序点亮;(KEY=2’b01)
		(3)左转弯时,右侧的指示灯全灭,左侧的指示灯按与右侧同样的循环顺序点亮;(KEY=2’b10)
		(4)如果在直行时刹车,两侧的指示灯全亮;如果在转弯时刹车,转弯这一侧的指示灯按上述的循环顺序点亮,另一侧的指示灯全亮。(KEY=2’b11)
实现方法:
	状态机:共六种状态:直行、左转、右转、直行刹车、左转刹车、右转刹车
	以一定周期去检测按键情况,实现状态切换
*/

module Transport_led(clk, k0, k1, led);
	input clk, k0, k1;
	output reg[7:0] led;
	
	parameter state_s=3'b000, state_l=3'b001, state_r=3'b010, state_ss=3'b011, state_ls=3'b100, state_rs=3'b101;//状态定义
	parameter[31:0] duration = 32'd12500000; //timer:500ms
	
	reg[2:0] current_state = state_s, next_state = state_s;
	reg[31:0] counter = 32'b0;
	reg delay_flag = 1'b0;
	reg delay_flag2 = 1'b0;
	
	reg[2:0] left_cycle = 3'b001;
	reg[2:0] right_cycle = 3'b100;

	//状态切换
	always@(posedge clk) begin
		current_state <= next_state;
		counter <= counter + 1'b1;
		if(counter >= duration-1) begin
			counter <= 0;
			delay_flag <= ~delay_flag;
			delay_flag2 <= ~delay_flag2;
		end
	end
	
	//下个状态变换
	always@(posedge delay_flag) begin
		case(current_state)
			state_s: begin
				if(~(k0|k1))
					next_state <= state_ss;
				else if(~k0)
					next_state <= state_l;
				else if(~k1)
					next_state <= state_r;
			end
			state_l: begin
				case({k1,k0})
					2'b00: next_state <= state_ls;
					2'b01: next_state <= state_r;
					2'b10: next_state <= state_l;
					2'b11: next_state <= state_s;
				endcase
				/*if(~(k0|k1))
					next_state <= state_ls;
				else if(~k1)
					next_state <= state_r;
				else if(k1&k0)
					next_state <= state_s;
				else
					next_state <= state_l;*/
			end
			state_r: begin
				case({k1,k0})
					2'b00: next_state <= state_rs;
					2'b01: next_state <= state_r;
					2'b10: next_state <= state_l;
					2'b11: next_state <= state_s;
				endcase
				/*if(~(k0|k1))
					next_state <= state_rs;
				else if(~k0)
					next_state <= state_l;
				else if(k1&k0)
					next_state <= state_s;
				else
					next_state <= state_r;*/
			end
			state_ss: begin
				if(k1&k0)
					next_state <= state_s;
				else if((k0==0) & (k1==0))
					next_state <= state_ss;
				else if(~k1)
					next_state <= state_r;
				else if(~k0)
					next_state <= state_l;
			end
			state_ls: begin
				if(k1&k0)
					next_state <= state_s;
				else if(~(k0|k1))
					next_state <= state_ls;
				else if(~k1)
					next_state <= state_r;
				else if(~k0)
					next_state <= state_l;
			end
			state_rs: begin
				if(k1&k0)
					next_state <= state_s;
				else if(~(k0|k1))
					next_state <= state_rs;
				else if(~k1)
					next_state <= state_r;
				else if(~k0)
					next_state <= state_l;
			end
		endcase
	end
	
	always@(posedge delay_flag2) begin
		case(current_state)
			state_s: begin
				led <= 8'b0;
			end
			state_l: begin
				led <= {left_cycle, 5'b0};
				left_cycle <= {left_cycle[1:0], left_cycle[2]};
			end
			state_r: begin
				led <= {5'b0, right_cycle};
				right_cycle <= {right_cycle[0], right_cycle[2:1]};
			end
			state_ss: begin
				led <= 8'b11100111;
			end
			state_ls: begin
				led <= {left_cycle, 5'b00111};
				left_cycle <= {left_cycle[1:0], left_cycle[2]};
			end
			state_rs: begin
				led <= {5'b11100, right_cycle};
				right_cycle <= {right_cycle[0], right_cycle[2:1]};
			end
		endcase
	end
endmodule

代码中引入一个500ms的定时器去定时检测按键k0、k1的电平状态,加以当前状态去判断下一时刻状态。

时序测试

汽车尾灯时序测试
无论是时序测试还是烧入到开发板测试,结果都与预期情况一致。

  • 7
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
好的,我会尝试回答你的问题。 Verilog HDL是一种硬件描述语言,可以用来描述数字电路的行为和结构。取指电路是计算机中非常重要的一部分,它负责从存储器中读取指令,然后将指令送到译码器中进行解码。下面是一个简单的Verilog HDL代码,用于实现取指电路: ``` module instruction_fetch( input clk, input reset, input [15:0] program_counter, output [15:0] instruction ); reg [15:0] memory [0:65535]; reg [15:0] next_program_counter; initial begin // 初始化存储器 $readmemh("program.hex", memory); end always @(posedge clk) begin if (reset) begin // 复位 next_program_counter <= 16'h0000; end else begin // 读取指令 instruction <= memory[program_counter]; next_program_counter <= program_counter + 16'h0001; end end assign program_counter = next_program_counter; endmodule ``` 以上代码中,我们定义了一个名为“instruction_fetch”的模块,其中包含4个端口:时钟clk、复位信号reset、程序计数器program_counter和指令instruction。在模块内部,我们定义了一个存储器数组memory,用于存储程序的指令。在初始化阶段,我们使用$readmemh函数从一个.hex文件中读取程序,并将其存储到存储器中。 在时钟上升沿的时候,我们检查复位信号是否为1。如果为1,我们将下一个程序计数器next_program_counter设置为0,以便重新从程序的第一条指令开始执行。如果复位信号为0,我们通过program_counter读取存储器中的指令,并将下一个程序计数器设置为program_counter + 1。 最后,我们使用assign语句将program_counter连接到next_program_counter,以便在下一个时钟周期中更新程序计数器的值。 当然,这只是一个简单的Verilog HDL代码示例,实际的取指电路可能更加复杂。但是,这个示例可以帮助你了解如何使用Verilog HDL实现取指电路。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值