8086接口缓存与同步串行发送的设计VHDL代码ModelSim 仿真
名称:8086接口缓存与同步串行发送的设计VHDL代码ModelSim 仿真
软件:ModelSim
语言:VHDL
代码功能
该工程实现一个带缓冲的串行发送模块:外部以8086兼容的片选/读写/地址信号写入8位数据,模块内部用环形缓冲区存储数据;在同步信号FS到来时,若缓冲区累计数据达到阈值,则按固定节拍把若干字节从高位到低位串行输出到TXD;若数据不足,则输出空闲字节用于占位,保证链路连续性。
代码实现思路
实现上把“并行写入”和“串行发送”分离:写入过程在2MHz时钟下对片选与写信号进行采样,将D总线数据写入数组并推进写指针;发送过程使用状态机等待FS的有效窗口,在满足“缓存中至少4字节”等条件后进入发送状态。每个字节通过位计数器控制移位输出,高位先出;当一个字节发送完成时产生读走脉冲推进读指针并更新待发送字节。这种结构既能适配不均匀的写入节奏,又能在同步场景下稳定地输出固定长度的帧数据。
代码结构
代码主体由三部分组成:1)环形缓冲区与读写指针,完成数据入队/出队统计;2)主状态机,决定当前输出空闲字节还是输出有效数据;3)位计数与移位逻辑,将字节转换为串行比特流。模块的关键接口是FS:FS有效时优先尝试输出有效数据帧;否则维持空闲字节输出。通过data_count限制出队条件,避免在帧发送过程中出现数据不完整。
FPGA代码Verilog/VHDL代码资源下载:www.hdlcode.com
演示视频:
设计文档:
1、程序文件

Testbench

2、程序编译

3、仿真图



部分代码
serial_data_tx.vhd
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.NUMERIC_STD.ALL; entity serial_data_tx is Port ( -- 8086兼容接口信号 WR_n : inSTD_LOGIC; -- 写信号(低有效) RD_n : inSTD_LOGIC; -- 读信号(低有效) D : in STD_LOGIC_VECTOR(7 downto 0); -- 双向数据线 A0 : inSTD_LOGIC; -- 地址线 CS_n : inSTD_LOGIC; -- 片选信号 -- 时钟和同步信号 CLK_2M: inSTD_LOGIC; -- 2.048MHz时钟 FS : inSTD_LOGIC; -- 同步信号(低有效) -- 串行输出 TXD : out STD_LOGIC -- 串行数据输出 ); end serial_data_tx; architecture Behavioral of serial_data_tx is -- 数据缓冲区 - 存储4个字节 type data_buffer_type is array (0 to 7) of STD_LOGIC_VECTOR(7 downto 0); signal data_buffer : data_buffer_type; signal write_ptr : integer range 0 to 7 := 0;-- 写指针 signal read_ptr : integer range 0 to 7 := 0;-- 读指针 signal data_count : integer range 0 to 8 := 0; -- 缓冲区中数据个数 signal FS_D : STD_LOGIC:='0'; signal ram_rd : STD_LOGIC:='0'; signal send_data : integer range 0 to 7 := 0; signal bit_count : integer range 0 to 7 := 0;--每个字节的位计数0~7 signal bit_count_d: integer range 0 to 7 := 0; signal preread_byte : STD_LOGIC_VECTOR(7 downto 0) := X"7E"; --当前发送的字节 signal current_send_byte : STD_LOGIC_VECTOR(7 downto 0) := X"7E"; --当前发送的字节 signal tx_byte : STD_LOGIC_VECTOR(7 downto 0) := X"7E"; --发送的字节 -- 状态机 type state_type is (IDLE, SYNC_WAIT, TRANSMIT, TRANS_DATA, TRANS_IDLE); signal current_state : state_type := IDLE; begin -- 8086兼容的读写接口 process(CLK_2M) begin if rising_edge(CLK_2M) then -- 写操作:向数据缓冲区写入数据 if CS_n = '0' and WR_n = '0' and A0 = '0' then if data_count < 8 then data_buffer(write_ptr) <= D; write_ptr <= (write_ptr + 1) mod 8; data_count <= data_count + 1; end if; elsif ram_rd = '1' then --读走 if data_count > 0 then data_count <= data_count - 1; --read_ptr <= (read_ptr + 1) mod 8; end if; end if; end if; end process; -- 主状态机 process(CLK_2M) begin if rising_edge(CLK_2M) then -- 主状态机 case current_state is when IDLE => current_state <= SYNC_WAIT; when SYNC_WAIT => --等待FS if FS = '0' then current_state <= TRANSMIT; else current_state <= TRANS_IDLE; end if; when TRANSMIT => --发送 if data_count >= 4 then --buffer中够4字节 current_state <= TRANS_DATA; else current_state <= TRANS_IDLE; end if; when TRANS_DATA => --发送数据 if send_data = 3 and bit_count = 7 then --已经发送4个字节 current_state <= TRANS_IDLE; else current_state <= TRANS_DATA; end if; when TRANS_IDLE => --发送空闲字节 if FS = '0'then --and bit_count = 7 if(data_count >= 4 )then current_state <= TRANS_DATA; else current_state <= TRANS_IDLE; end if; else current_state <= TRANS_IDLE; end if; when others => current_state <= IDLE; end case; end if; end process; --控制send_data,发送的字节数 process(CLK_2M) begin if rising_edge(CLK_2M) then case current_state is when TRANSMIT => send_data <= 0; -- 重置发送字节计数 when TRANS_DATA => if bit_count = 7 then -- 一个字节发送完成 if send_data < 3 then send_data <= send_data + 1; else send_data <= 0; end if; end if; when TRANS_IDLE => send_data <= 0; -- 重置发送字节计数 when others => null; end case; end if; end process; --控制bit_count--每个字节的位计数 process(CLK_2M) begin if rising_edge(CLK_2M) then case current_state is when TRANSMIT => bit_count <= 0; -- 重置位计数 when TRANS_DATA | TRANS_IDLE => if bit_count = 7 then bit_count <= 0; -- 一个字节发送完成,重置位计数 else bit_count <= bit_count + 1; -- 位计数递增 end if; when others => null; end case; end if; end process; --控制每次发送的字节内容 process(CLK_2M) begin if rising_edge(CLK_2M) then -- 默认ram_rd为低电平 ram_rd <= '0'; case current_state is -- when TRANSMIT => --进入发送状态时,准备第一个字节 -- if data_count >= 4 then -- preread_byte <= data_buffer(read_ptr); -- else -- preread_byte <= X"7E"; -- 空闲字节 -- end if; when TRANS_DATA => if bit_count = 0 then -- 当前字节发送完成,准备下一个字节 -- 产生ram_rd脉冲,表示读走一个数据 ram_rd <= '1'; read_ptr <= (read_ptr + 1) mod 8; -- 准备下一个字节 preread_byte <= data_buffer(read_ptr); end if; when TRANS_IDLE => preread_byte <= X"7E"; -- 空闲字节 when others => null; end case; end if; end process; process(CLK_2M) begin if rising_edge(CLK_2M) then bit_count_d<=bit_count; current_send_byte<=preread_byte; end if; end process; -- tx_byte<=std_logic_vector(shift_left(unsigned (preread_byte),bit_count)); -- 数据左移 -- TXD <= tx_byte(7);--最终输出移位后信号的最高位 -- 控制将待发送的字节转换为串行输出,高位在前 process(current_state,preread_byte,bit_count_d) begin case current_state is when IDLE | SYNC_WAIT => TXD <= '0'; -- 空闲时输出高电平 tx_byte<=X"7E"; when TRANSMIT => TXD <= '0'; -- 准备发送时输出高电平 when TRANS_DATA | TRANS_IDLE => ---数据左移
代码文件(付费下载):
![]()
![]()
2、支付问题请联系微信公众号客服。
3、优质Verilog/VHDL代码资源,所见即所得。
Verilog/VHDL资源下载 » 8086接口缓存与同步串行发送的设计VHDL代码ModelSim 仿真
发表评论
模板文件不存在: ./template/plugins/comment/pc/index.htm