Verilog 学习之路(三)——牛客刷题篇

1.输入序列连续的序列检测

  • 题面
  • 思路

对于序列检测题目,常规的解法有两种:状态机法和序列缓存对比法。

状态机法的过程类似于:在初始状态中,先判断第一位是否符合,若符合则进入下一个状态,判断第二位是否符合;若第一位不符合则保持在初始状态,直到第一位匹配。如前两位匹配,则判断第三位是否符合,若第一位匹配,最新输入的数值和目标序列的第二位不匹配,则根据最新一位是否匹配第一位,进入第一位匹配状态或者初始状态。依次类推。

序列缓存对比法,则是将八个时刻的数据缓存,作为一个数组,每个时刻的输入位于数组的末尾,数组其它元素左移,把最早输入的数据移出。然后将数组和目标序列对比,如果数组和目标序列相等,则说明出现目标序列。

序列缓存对比法在实现上比较简单。首先声明一个数组,缓存八个时刻的a输入的数值。移位可以通过位截取操作和位拼接操作实现:a_tem[6:0]表示截取a_tem的低7位,{a_tem[6:0],a}表示把a_tem[6:0]和新输入的数值a拼接,a位于低位。

  • 代码
verilog 复制代码
`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input a,
	output reg match
	);
	reg [7:0] a_tem;
	always @(posedge clk or negedge rst_n) begin
		if (!rst_n) begin
			match <=1'b0;
		end
		else if (a_tem == 8'b0111_0001) begin
			match <= 1'b1;
		end
		else begin
			match <= 1'b0;
		end
	end

	always @(posedge clk or negedge rst_n) begin
		if (!rst_n) begin
			a_tem <= 8'b0;
		end
		else begin
			a_tem <= {a_tem[6:0],a};
		end
	end
  
endmodule

2.含有无关项的序列检测

  • 题面
  • 思路

序列缓存对比法,则是将九个时刻的数据缓存,作为一个数组,每个时刻的输入位于数组的末尾,数组其它元素左移,把最早输入的数据移出。然后截取数组的前三位和目标序列011对比,截取数组的后三位和目标序列110对比,如果两段数组都和目标序列相等,则说明出现目标序列。

序列缓存对比法在实现上比较简单,本题采用该方法实现。首先声明一个数组,缓存九个时刻的a输入的数值。移位可以通过位截取操作和位拼接操作实现:a_tem[7:0]表示截取a_tem的低7位,{a_tem[7:0],a}表示把a_tem[7:0]和新输入的数值a拼接,a位于低位。

  • 代码

    `timescale 1ns/1ns
    module sequence_detect(
    input clk,
    input rst_n,
    input a,
    output match
    );
    reg [8:0] a_tem;
    reg match_f;
    reg match_b;

    复制代码
      always @(posedge clk or negedge rst_n) begin
          if (!rst_n) begin
              match_f <=1'b0;
          end
          else if (a_tem[8:6] == 3'b011) begin
              match_f <= 1'b1;
          end
          else begin
              match_f <= 1'b0;
          end
      end
    
      always @(posedge clk or negedge rst_n) begin
          if (!rst_n) begin
              match_b <= 1'b0;
          end
          else if (a_tem[2:0] == 3'b110) begin
              match_b <= 1'b1;
          end
          else begin
              match_b <= 1'b0;
          end
      end
    
      always @(posedge clk or negedge rst_n) begin
          if (!rst_n) begin
              a_tem <= 9'b0;
          end 
          else begin
              a_tem <= {a_tem[7:0],a};
          end
      end
    
      assign match = match_b && match_f;

    endmodule

  • 解法2

    `timescale 1ns/1ns
    module sequence_detect(
    input clk,
    input rst_n,
    input a,
    output reg match
    );
    reg [8:0] sequence;

    复制代码
      always @(posedge clk or negedge rst_n) begin
      	if (~rst_n) begin
      		sequence <= 9'b0;
      	end
      	else begin
      		sequence <= {sequence[7:0],a};
      	end
      end
    
      always @(posedge clk or negedge rst_n) begin
      	if (~rst_n) begin
      		match <= 0;
      	end
      	else if (sequence[8:6] == 3'b011 && sequence[2:0] == 3'b110) begin
      		match <= 1;
      	end
      	else begin
      		match <= 0;
      	end
      end

    endmodule

  • 解法3

    `timescale 1ns/1ns
    module sequence_detect(
    input clk,
    input rst_n,
    input a,
    output reg match
    );
    reg [8:0] val;

    复制代码
      always @(posedge clk or negedge rst_n) begin
          if (!rst_n) begin
              val <= 9'b0;
          end else begin
              val <= {val[7:0],a};
          end
      end
      
      always @(posedge clk or negedge rst_n) begin
          if (!rst_n) begin
              match <= 1'b0;
          end else begin
              casex (val)
                  9'b011xxx110 : match <= 1'b1;
                  default : match <= 1'b0;
              endcase
          end
      end

    endmodule

3. 不重叠序列检测

  • 题意

    题目描写错误,应该是001110,而题目是011100,差评。
  • 思路
相关推荐
whoarethenext1 小时前
C++ OpenCV 学习路线图
c++·opencv·学习
恰薯条的屑海鸥1 小时前
零基础在实践中学习网络安全-皮卡丘靶场(第十四期-XXE模块)
网络·学习·安全·web安全·渗透测试
Lester_11011 小时前
嵌入式学习笔记 - freeRTOS vTaskPlaceOnEventList()函数解析
笔记·学习
moxiaoran57533 小时前
uni-app学习笔记二十三--交互反馈showToast用法
笔记·学习·uni-app
GateWorld7 小时前
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析LLP (二)
fpga开发·mipi csi2
恰薯条的屑海鸥10 小时前
零基础在实践中学习网络安全-皮卡丘靶场(第十六期-SSRF模块)
数据库·学习·安全·web安全·渗透测试·网络安全学习
喜欢吃燃面11 小时前
C++刷题:日期模拟(1)
c++·学习·算法
2301_7976042412 小时前
学习记录:DAY32
学习
蓝婷儿12 小时前
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
开发语言·python·学习
叶子20242213 小时前
学习使用YOLO的predict函数使用
人工智能·学习·yolo