【数字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文件会以递归的形式呈现,严格…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...

算法—栈系列
一:删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...
2025.6.9总结(利与弊)
凡事都有两面性。在大厂上班也不例外。今天找开发定位问题,从一个接口人不断溯源到另一个 接口人。有时候,不知道是谁的责任填。将工作内容分的很细,每个人负责其中的一小块。我清楚的意识到,自己就是个可以随时替换的螺丝钉&…...
OpenGL-什么是软OpenGL/软渲染/软光栅?
软OpenGL(Software OpenGL)或者软渲染指完全通过CPU模拟实现的OpenGL渲染方式(包括几何处理、光栅化、着色等),不依赖GPU硬件加速。这种模式通常性能较低,但兼容性极强,常用于不支持硬件加速…...