【数字IC/FPGA】手撕代码:模3检测器(判断输入序列能否被3整除)
今天我们来手撕一个常见的笔试题,使用的方法是三段式Moore状态机。
题目描述:
输入端口是串行的1bit数据,每个时钟周期进来一位新数据后,实时检查当前序列是否能整除3,若能则输出1,否则输出0。
例如,在4个时钟周期依次输入的数据为1、1、0、1。则有:
T1:数据序列为1(10进制的1),不能为3整除,所以输出flag = 0;
T2:数据序列为11(10进制的3),能为3整除,所以输出flag = 1;
T3:数据序列为110(10进制的6),能为3整除,所以输出flag = 1;
T4:数据序列为1101(10进制的13),不能为3整除,所以输出flag = 0;
接着简单分析一下题目。一个整数被3除后的余数情况只有3种:
- 余数为0
- 余数为1
- 余数为2
假设当前序列表示的数是num,它除3的商为a,余数为b, 则这个数num可以这么表示:
num = 3a + b
因为每个时钟周期新进来的数都是放入数据序列的最低位,其他位则是往左移1位,而左移一位等价于乘以2,再加上新进来的数c(c要么是0、要么是1)后,那么每个新的周期都有新序列:
新的序列 num_n = num * 2 + c
例如,前3个周期分别输入数据1、1、0,则有 110 即 6 = 3 * 2 + 0 (商a=2、余b=0);在T4时刻输入1,则1101即13 = 6 * 2 + 1(旧的num = 6,新的输入c = 1 )。
知道这些后可以对3种余数情况来分别进行讨论:
(1)余数为0的情况,也就是数据可以表示为 num = 3a + b = 3a + 0
- 新的输入为0,则新的序列为num_n = 2*num + 0 = 6*a,说明此时可以被3整除
- 新的输入为1,则新的序列为num_n = 2*num + 1 = 6*a + 1,说明此时不可以被3整除,余数为1
(2)余数为1的情况,也就是数据可以表示为 num = 3a + b = 3a + 1
- 新的输入为0,则新的序列为num_n = 2*num + 0 = 6*a + 2,说明此时不可以被3整除,余数为2
- 新的输入为1,则新的序列为num_n = 2*num + 1 = 6*a + 3,说明此时可以被3整除
(3)余数为2的情况,也就是数据可以表示为 num = 3a + b = 3a + 2
- 新的输入为0,则新的序列为num_n = 2*num + 0 = 6*a + 4,说明此时不可以被3整除,余数为1
- 新的输入为1,则新的序列为num_n = 2*num + 1 = 6*a + 5,说明此时不可以被3整除,余数为2
把这些情况划分为不同的状态,状态之间的跳转参考上面的分析。一共划分4个状态,分别是:
- IDLE:初始状态,状态跳转条件同S3,但是该状态不会输出有效信号
- S1:余数为1的状态,该状态不会输出有效信号
- S2:余数为2的状态,该状态不会输出有效信号
- S3:余数为0的状态,此时拉高有效信号flag
状态跳转图如下:

有了这些信息后,Moore型的三段式状态机也很容易写了:
//串行输入数据,实时输出当前数据能否被3整除。
//新的输入为低位,之前输入为高位。例如依次输入1、0,则视为10,而非01
module test(input clk,input rst, input in, //串行输入output reg flag //输入能被3整除时输出1,其他0
);//定义状态寄存器
reg [1:0] state_cur;
reg [1:0] state_next;//参数化状态变量
localparam IDLE = 2'b00;
localparam S1 = 2'b01;
localparam S2 = 2'b10;
localparam S3 = 2'b11;//三段式状态机的状态变化
always@(posedge clk) beginif(rst) state_cur <= IDLE;else state_cur <= state_next;
end//三段式状态机的状态转移条件
always@(*)beginif(rst) state_next = IDLE;else begincase(state_cur)IDLE: state_next = in ? S1 : S3; S1 : state_next = in ? S3 : S2; S2 : state_next = in ? S2 : S1; S3 : state_next = in ? S1 : S3;default:state_next = IDLE;endcaseend
end//三段式状态机的输出
always@(posedge clk) beginif(rst) flag <= 0;else begincase(state_next)S3: flag <= 1'b1;default: flag <= 1'b0;endcaseend
endendmodule
再写个TB来测试一下模块的正确性,测试逻辑是这样的:
复位完成后,在每个时钟周期随机生成1bit输入,在TB内根据每个周期的输入实时生成数据num来统计所有的串行输入的值,比如前4个周期依次生成输入1、1、0、1,则num的值分别为1、11、110、1101,即10进制的1、3、6、12。
每个周期都用%运算符(TB文件不用考虑能否综合的问题)来对num取模,并将取模结果与被测模块的结果做比较,若二者有误,则拉高错误标志error;否则不拉高error。
`timescale 1ns/1nsmodule tb_test();reg clk;
reg rst;
reg in;
wire flag;reg [127:0] num; //记录输入数据的数值大小
reg error; //错误标志
wire [1:0] rem; //除3的余数assign rem = (num % 3);//生成时钟信号,周期10ns
initial beginclk = 1'b1;forever #5 clk = ~clk;
end//生成高电平有效的同步复位信号,持续3个周期
initial beginrst = 1;#30rst <= 0;
endalways@(posedge clk) beginif(rst)begin in <= 0;num <= 0;error <= 0;endelse beginin <= #1 $random & $random; //输入是随机的0或1num <= (num << 1) + in; //依次左移并加上最新的输入来统计数据大小if((rem == 2'd0) != flag)begin //如果二者有误$display("ERROR %d",num);error = 1;end else error = 0; end
endinitial begin#300 $stop(); //一段时间后结束仿真
end//例化被测试模块
test inst_test(.clk (clk ),.rst (rst ), .in (in ),.flag (flag )
);endmodule
仿真结果如下:

可见,串行输入分别为00110100010,分别对应10进制数据0、0、1、3、6、13、26、52、104、208、417、834,在输入序列分别为10进制的0、0、3、6、417、834时输出flag为高,说明这些数据能被3整除。
需要额外说明的有两点:
- 输出采用了时序逻辑,所以会慢一拍。例如在输入为0011的下一拍,flag才拉高。
- 尽管error在最一开始被拉高了一次,但并不说明模块功能发生了错误。error拉高的原因是因为在初始状态时,flag没有设计被拉高,但此时的数据值在TB中被视为0,也就是意味着在TB中是可以被3整除的,这就造成了二者的出入。这个情况忽略掉就行。
相关文章:
【数字IC/FPGA】手撕代码:模3检测器(判断输入序列能否被3整除)
今天我们来手撕一个常见的笔试题,使用的方法是三段式Moore状态机。 题目描述: 输入端口是串行的1bit数据,每个时钟周期进来一位新数据后,实时检查当前序列是否能整除3,若能则输出1,否则输出0。 例如&#…...
最小可行产品需要最小可行架构——可持续架构(三)
前言 最小可行产品(MVP)的概念可以帮助团队专注于尽快交付他们认为对客户最有价值的东西,以便在投入大量时间和资源之前迅速、廉价地评估产品的市场规模。MVP不仅需要考虑产品的市场可行性,还需要考虑其技术可行性,以…...
笔记: 数据结构与算法--时间复杂度二分查找数组
算法复杂度 不依赖于环境因素事前分析法 计算最坏情况的时间复杂度每一条语句的执行时间都按照t来计算 时间复杂度 大O表示法 n 数据量 ; f(n) 实际的执行条数当存在一个n0 , 使得 n > n0,并且 c * g(n) 恒> f(n) : 渐进上界(算法最坏的情况)那么f(n)的时间复杂度 …...
AI绘画教程:Midjourney使用方法与技巧从入门到精通
文章目录 一、《AI绘画教程:Midjourney使用方法与技巧从入门到精通》二、内容介绍三、作者介绍🌤️粉丝福利 一、《AI绘画教程:Midjourney使用方法与技巧从入门到精通》 一本书读懂Midjourney绘画,让创意更简单,让设计…...
Spring-事务管理
1、事务管理 1.1、回滚方式 默认回滚方式:发生运行异常时异常和error时回滚,发生受查(编译)异常时提交。不过,对于受查异常,程序员也可以手工设置其回滚方式 1.2、事务定义接口 1.2.1、事务隔离级别常量 这些常量…...
MySql实战--为什么我的MySQL会“抖”一下
时的工作中,不知道你有没有遇到过这样的场景,一条SQL语句,正常执行的时候特别快,但是有时也不知道怎么回事,它就会变得特别慢,并且这样的场景很难复现,它不只随机,而且持续时间还很短…...
【蓝桥杯第十三届省赛B】(部分详解)
九进制转十进制 #include <iostream> #include<math.h> using namespace std; int main() {cout << 2*pow(9,3)0*pow(9,2)2*pow(9,1)2*pow(9,0) << endl;return 0; }顺子日期 #include <iostream> using namespace std; int main() {// 请在此…...
[linux初阶][vim-gcc-gdb] OneCharter: vim编辑器
一.vim编辑器基础 目录 一.vim编辑器基础 ①.vim的语法 ②vim的三种模式 ③三种模式的基本切换 ④各个模式下的一些操作 二.配置vim环境 ①手动配置(不推荐) ②自动配置(推荐) vim是vi的升级版,包含了更加丰富的功能. ①.vim的语法 vim [文件名] ②vim的三种模式 命令…...
【Lazy ORM 框架学习】
Gitee 点赞关注不迷路 项目地址 快速入门 模块所属层级描述快照版本正式版本wu-database-lazy-lambdalambda针对不同数据源wu-database-lazy-orm-coreorm 核心orm核心处理wu-database-lazy-sqlsql核心处理成处理sql解析、sql执行、sql映射wu-elasticsearch-starterESESwu-hb…...
安科瑞路灯安全用电云平台解决方案【电不起火、电不伤人】
背景介绍 近年来 ,随着城市规模的不断扩大 ,路灯事业蓬勃发展。但有的地方因为观念、技术、管理等方面不完善 ,由此引发了一系列安全问题。路灯点多面广 ,一旦漏电就极容易造成严重的人身安全事故。不仅给受害者家庭带来痛苦 &am…...
MYSQL——索引概念索引结构
索引 索引是帮助数据库高效获取数据的排好序的数据结构。 有无索引时,查询的区别 主要区别在于查询速度和系统资源的消耗。 查询速度: 在没有索引的情况下,数据库需要对表中的所有记录进行扫描,以找到符合查询条件的记录&#…...
Linux(CentOS7)配置系统服务以及开机自启动
目录 前言 两种方式 /etc/systemd/system/ 进入 /etc/systemd/system/ 文件夹 创建 nginx.service 文件 重新加载 systemd 配置文件 编辑 配置开机自启 /etc/init.d/ 进入 /etc/init.d/ 文件夹 创建 mysql 文件 编写脚本内容 添加/删除系统服务 配置开机自启 …...
0 决策树基础
目录 1 绪论 2 模型 3 决策树面试总结 1 绪论 决策树算法包括ID3、C4.5以及C5.0等,这些算法容易理解,适用各种数据,在解决各种问题时都有良好表现,尤其是以树模型为核心的各种集成算法,在各个行业和领域都有广泛的…...
Linux速览(2)——环境基础开发工具篇(其一)
本章我们来介绍一些linux的常用工具 目录 一. Linux 软件包管理器 yum 1.什么是软件包? 2. 查看软件包 3. 如何安装软件 4. 如何卸载软件 5.yum补充 6. 关于 rzsz 二. Linux编辑器-vim使用 1. vim的基本概念 2. vim的基本操作 3. vim正常模式命令集 4. vim末行模式…...
AWS SES发送邮件时常见的错误及解决方法?
AWS SES发送邮件如何做配置?使用AWS SES发信的限制? 在使用AWS SES发送邮件时,可能会遇到一些常见的错误。AokSend将介绍一些常见的AWS SES发送邮件错误及其相应的解决方法,帮助用户更好地利用AWS SES进行邮件发送。 AWS SES发送…...
视频基础学习三——视频帧率、码率与分辨率
文章目录 前言一、介绍1.定义2.三者之间的关系 总结 前言 在之前的文章中详细介绍了一些关于图像的色彩与格式,而视频其实就是由一张张图片进行展示呈现出来的。 我们会经常说一段视频的质量好不好,而什么是视频的质量呢?博主的个人理解就是…...
Spring(详细介绍)
目录 一、简介 1、什么是Spring? 2、Spring框架的核心特性 3、优点 二、IOC容器 介绍 1、获取资源的传统方式 2、控制反转方式获取资源 3、DI 4、IOC容器在Spring中的实现 入门案例 1、创建Maven Module 2、引入依赖 3、创建HelloWorld类 4、在Spring的配…...
Kettle使用
1.准备工作 KETTLE-5.4.zip HANA环境192.168.xx.xx 用户名:system 密码:****** 端口号:30015 Oracle环境 192.168.xx.xx 用户名 HANA_TEST 密码 ****** 端口号:31001 配置java环境变量 因为本次数据转换测试为将HANA数据转换到Or…...
互联网摸鱼日报(2024-04-01)
互联网摸鱼日报(2024-04-01) 36氪新闻 「矽迪半导体」获数千万天使轮融资,提供高效功率半导体方案|硬氪首发 本周双碳大事:国资委即将发布央企ESG指导意见;上海发文推动建立产品碳足迹管理体系;隆基新硅片面世 数字…...
pnpm比npm、yarn好在哪里?
前言 pnpm对比npm/yarn的优点: 更快速的依赖下载更高效的利用磁盘空间更优秀的依赖管理 我们按照包管理工具的发展历史,从 npm2 开始讲起: npm2 使用早期的npm1/2安装依赖,node_modules文件会以递归的形式呈现,严格…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
