news 2026/8/1 10:17:35

简易寄存器接口SMMR---正交编码器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
简易寄存器接口SMMR---正交编码器

参考

简易寄存器接口SMMR的vio_uart桥接.csdn
Tang-Nano-1K.sipeed

TANG_FPGA_Demo_Top.v

module TANG_FPGA_Demo_Top#( // 内部 SMMR 字节地址宽度。 parameter P_ADDR_WIDTH = 8, // 寄存器宽度 parameter P_DATA_WIDTH = 32, // 系统时钟频率。 parameter P_CLK_FREQ = 27_000_000 ) ( input CLOCK_XTAL_27MHz, input RESET, input KEY1, input RXD, output TXD, input ENCORDER_A, input ENCORDER_B, output [2:0] LED // 110 R, 101 B, 011 G ); //////////////////////////////////////////////////////////////////////////// // vio_uart桥接模块到 SMMR 路由模块之间的信号 //////////////////////////////////////////////////////////////////////////// wire w_reg_wr_en; wire [8-1:0] w_reg_wr_addr; wire [8-1:0] w_reg_rd_addr; wire [P_DATA_WIDTH-1:0] w_reg_wr_data; wire [P_DATA_WIDTH-1:0] w_reg_rd_data; wire [P_ADDR_WIDTH-1:0] w_slot_wr_addr; wire [P_ADDR_WIDTH-1:0] w_slot_rd_addr; // 写数据会同时送到所有 slot,真正写入哪个 slot 由对应写使能决定。 wire [P_DATA_WIDTH-1:0] w_slot_wr_data; // slot0 的写使能和读数据。 wire w_slot0_wr_en; wire [P_DATA_WIDTH-1:0] w_slot0_rd_data; // slot1 的写使能和读数据。 wire w_slot1_wr_en; wire [P_DATA_WIDTH-1:0] w_slot1_rd_data; vio_uart_smmr_bridge #( .P_CLK_FREQ(P_CLK_FREQ), .P_UART_BPS(115200) ) u_vio_uart_smmr_bridge ( .i_clk (CLOCK_XTAL_27MHz), .i_rst_n (RESET), .i_uart_rxd (RXD), .o_uart_txd (TXD), .o_reg_wr_en (w_reg_wr_en), .o_reg_wr_addr (w_reg_wr_addr), .o_reg_wr_data (w_reg_wr_data), .o_reg_rd_addr (w_reg_rd_addr), .i_reg_rd_data (w_reg_rd_data) ); //////////////////////////////////////////////////////////////////////////// // SMMR slot 路由模块 // // 该模块根据 SMMR 地址范围选择目标 slot。 // 写操作时,它给对应 slot 产生写使能。 // 读操作时,它把被选中 slot 的读数据返回给 AXI-Lite 桥接模块。 // // 当前地址映射: // slot0:寄存器地址 0 到 3 // slot1:寄存器地址 5 到 8 //////////////////////////////////////////////////////////////////////////// smmr_slot_router u_smmr_slot_router ( .i_clk (CLOCK_XTAL_27MHz), .i_rst_n (RESET), .i_reg_wr_en (w_reg_wr_en), .i_reg_wr_addr (w_reg_wr_addr), .i_reg_wr_data (w_reg_wr_data), .i_reg_rd_addr (w_reg_rd_addr), .o_reg_rd_data (w_reg_rd_data), .o_slot_wr_addr (w_slot_wr_addr), .o_slot_wr_data (w_slot_wr_data), .o_slot_rd_addr (w_slot_rd_addr), .o_slot0_wr_en (w_slot0_wr_en), .i_slot0_rd_data(w_slot0_rd_data), .o_slot1_wr_en (w_slot1_wr_en), .i_slot1_rd_data(w_slot1_rd_data) ); //////////////////////////////////////////////////////////////////////////// // slot0 外设 // // slot0 是一个简单寄存器块。 // 它可以作为新增 SMMR 外设的模板:只需要接入写使能、地址、写数据、 // 读地址和读数据,就可以挂到系统中。 //////////////////////////////////////////////////////////////////////////// slot0 u_slot0 ( .i_clk (CLOCK_XTAL_27MHz), .i_rst_n (RESET), .i_reg_wr_en (w_slot0_wr_en), .i_reg_wr_addr (w_slot_wr_addr), .i_reg_wr_data (w_slot_wr_data), .i_reg_rd_addr (w_slot_rd_addr), .o_reg_rd_data (w_slot0_rd_data) ); //////////////////////////////////////////////////////////////////////////// // slot1 编码器外设 //////////////////////////////////////////////////////////////////////////// encoder_slot u_slot1 ( .i_clk (CLOCK_XTAL_27MHz), .i_rst_n (RESET), .i_encoder_a(ENCORDER_A), .i_encoder_b(ENCORDER_B), .i_reg_wr_en (w_slot1_wr_en), .i_reg_wr_addr (w_slot_wr_addr), .i_reg_wr_data (w_slot_wr_data), .i_reg_rd_addr (w_slot_rd_addr), .o_reg_rd_data (w_slot1_rd_data) ); endmodule

encoder_slot .v

`timescale 1ns / 1ps module encoder_slot #( parameter P_ADDR_WIDTH = 8, parameter P_DATA_WIDTH = 32, parameter [P_ADDR_WIDTH-1:0] P_SLOT_BASE = 4, parameter P_REG_COUNT = 1 )( input wire i_clk, input wire i_rst_n, // SMMR input wire i_reg_wr_en, input wire [P_ADDR_WIDTH-1:0] i_reg_wr_addr, input wire [P_DATA_WIDTH-1:0] i_reg_wr_data, input wire [P_ADDR_WIDTH-1:0] i_reg_rd_addr, output reg [P_DATA_WIDTH-1:0] o_reg_rd_data, // Encoder input wire i_encoder_a, input wire i_encoder_b ); //////////////////////////////////////////////////////////////////////////// // 内部寄存器 //////////////////////////////////////////////////////////////////////////// reg signed [15:0] r_encoder_value; reg [1:0] r_old_code; reg [1:0] r_encoder_sync1; reg [1:0] r_encoder_sync2; //////////////////////////////////////////////////////////////////////////// // 输入同步 //////////////////////////////////////////////////////////////////////////// always @(posedge i_clk or negedge i_rst_n) begin if (!i_rst_n) begin r_encoder_sync1 <= 2'b00; r_encoder_sync2 <= 2'b00; end else begin // A = bit0 // B = bit1 r_encoder_sync1 <= {i_encoder_b, i_encoder_a}; r_encoder_sync2 <= r_encoder_sync1; end end //////////////////////////////////////////////////////////////////////////// // 编码器解码 //////////////////////////////////////////////////////////////////////////// always @(posedge i_clk or negedge i_rst_n) begin if (!i_rst_n) begin r_old_code <= 2'b00; r_encoder_value <= 16'd0; end else if (r_encoder_sync2 != r_old_code) begin case (r_encoder_sync2) 2'b00: begin if (r_old_code == 2'b10) r_encoder_value <= r_encoder_value + 16'd1; else if (r_old_code == 2'b01) r_encoder_value <= r_encoder_value - 16'd1; end 2'b01: begin if (r_old_code == 2'b00) r_encoder_value <= r_encoder_value + 16'd1; else if (r_old_code == 2'b11) r_encoder_value <= r_encoder_value - 16'd1; end 2'b11: begin if (r_old_code == 2'b01) r_encoder_value <= r_encoder_value + 16'd1; else if (r_old_code == 2'b10) r_encoder_value <= r_encoder_value - 16'd1; end 2'b10: begin if (r_old_code == 2'b11) r_encoder_value <= r_encoder_value + 16'd1; else if (r_old_code == 2'b00) r_encoder_value <= r_encoder_value - 16'd1; end endcase r_old_code <= r_encoder_sync2; end end //////////////////////////////////////////////////////////////////////////// // SMMR Read //////////////////////////////////////////////////////////////////////////// always @(*) begin if ((i_reg_rd_addr >= P_SLOT_BASE) && (i_reg_rd_addr < (P_SLOT_BASE + P_REG_COUNT))) begin // 符号扩展到32位 o_reg_rd_data = {{16{r_encoder_value[15]}}, r_encoder_value}; end else begin o_reg_rd_data = {P_DATA_WIDTH{1'b0}}; end end endmodule

ReadMe.md

set src_dir "D:/workspace/gitee/0/ming_tang_nano_1k/vio_uart/src" set rtl_dir "D:/workspace/gitee/0/ming_tang_nano_1k/vio_uart/src/rtl" add_file $rtl_dir/TANG_FPGA_Demo_Top.v add_file $rtl_dir/uart_rx.v add_file $rtl_dir/uart_tx.v add_file $rtl_dir/vio_uart_smmr_bridge.v add_file $rtl_dir/smmr_slot_router.v add_file $rtl_dir/slot0.v add_file $rtl_dir/encoder_slot.v add_file $src_dir/vio_uart_prj.cst add_file $src_dir/vio_uart_prj.sdc

vio_uart_prj.cst

IO_LOC"CLOCK_XTAL_27MHz"47;IO_PORT"CLOCK_XTAL_27MHz"IO_TYPE=LVCMOS33PULL_MODE=UP;IO_LOC"RESET"13;IO_PORT"RESET"IO_TYPE=LVCMOS33PULL_MODE=UP;IO_LOC"KEY1"44;IO_PORT"KEY1"IO_TYPE=LVCMOS33PULL_MODE=UP;IO_LOC"TXD"40;IO_PORT"TXD"IO_TYPE=LVCMOS33PULL_MODE=UPDRIVE=8;IO_LOC"RXD"41;IO_PORT"RXD"IO_TYPE=LVCMOS33PULL_MODE=UP;IO_LOC"LED[2]"11;IO_PORT"LED[2]"IO_TYPE=LVCMOS33PULL_MODE=UPDRIVE=8;IO_LOC"LED[1]"10;IO_PORT"LED[1]"IO_TYPE=LVCMOS33PULL_MODE=UPDRIVE=8;IO_LOC"LED[0]"9;IO_PORT"LED[0]"IO_TYPE=LVCMOS33PULL_MODE=UPDRIVE=8;IO_LOC"ENCORDER_A"38;IO_PORT"ENCORDER_A"IO_TYPE=LVCMOS33PULL_MODE=UP;IO_LOC"ENCORDER_B"39;IO_PORT"ENCORDER_B"IO_TYPE=LVCMOS33PULL_MODE=UP;

测试

# 查编码器值>00 04 00 00 00 00# 返回编码器值是16<00 041000 00 00
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/1 10:17:30

为何企业迫切需要ITSM平台?ITSM平台落地常见难点

在越来越数字化的企业环境中&#xff0c;IT 服务管理的重要性日益凸显。很多企业都意识到&#xff0c;需要一个ITSM平台来规范 IT 服务流程、提升服务效率、确保服务质量。然而&#xff0c;从理念到落地往往困难重重。 一、为何企业迫切需要ITSM平台 随着企业规模扩大、系统种类…

作者头像 李华
网站建设 2026/8/1 10:13:42

【回眸】副业灵感——银发经济消费项目前景分析

走在街头巷尾&#xff0c;你会发现一个明显的变化&#xff1a;公园里的晨练队伍中&#xff0c;银发族的身影越来越多&#xff0c;社区周边的便利店开始增设无障碍通道&#xff0c;手机 APP 的字体也在悄悄变大。这不仅仅是人口结构变化的直观体现&#xff0c;更是一个庞大市场正…

作者头像 李华
网站建设 2026/8/1 10:13:31

Hive表结构变更实战:添加、修改、删除列的原理与避坑指南

1. 项目概述&#xff1a;Hive表结构变更的实战指南在数据仓库的日常运维和开发中&#xff0c;数据表的结构从来都不是一成不变的。业务需求的迭代、数据源的调整、性能优化的考量&#xff0c;都要求我们能够灵活地对已有的Hive表进行结构调整。今天要聊的&#xff0c;就是每个数…

作者头像 李华
网站建设 2026/8/1 10:13:24

Excel VBA复制粘贴与动态区域选择:从基础语法到高效自动化实战

1. 项目概述&#xff1a;为什么VBA的“复制粘贴”值得深挖&#xff1f; 干了十几年数据处理&#xff0c;我见过太多同事在Excel里重复着机械的“CtrlC”和“CtrlV”。表面上看&#xff0c;这操作简单到不值一提&#xff0c;但一旦你开始用VBA&#xff08;Visual Basic for Appl…

作者头像 李华
网站建设 2026/8/1 10:07:18

为什么选择零信脱敏?不只是因为识别准确率

自发布以来&#xff0c;零信脱敏已服务银行、医院、律师事务所和财税服务机构等客户&#xff0c;并应用于政务相关材料处理场景&#xff0c;也获得了美国、波兰等海外企业客户的选择。 这些客户处理的往往不是普通文件&#xff0c;而是合同、卷宗、标书、病历、财务资料和内部文…

作者头像 李华
网站建设 2026/8/1 10:03:45

桌面多功能交互终端开发指南:USB与蓝牙HID协议实战

如果你正在为桌面设备连接混乱、线缆缠绕、多设备切换不便而烦恼&#xff0c;那么"桌面多功能交互终端"这个概念可能正是你需要的解决方案。这不仅仅是一个简单的USB扩展坞&#xff0c;而是一个集成了USB协议、蓝牙连接、触控板控制、磁吸固定等多种功能的智能终端设…

作者头像 李华