VHDL语法入门 (四) 并行与串行

FPGA之道(29)VHDL的串行语句 在VHDL中,串行语句的顺序执行只是一种帮助开发者、编译器、仿真器等理解代码、描述功能的一个辅助“思路”,而代码真正对应的硬件结构肯定是并行的! 阅读详情
AI摘要

本文详细介绍了VHDL中的并发代码,包括when语句(when/else和when/select/when)、generate语句以及块语句,强调了并发执行的特点。同时,也阐述了顺序代码,如进程(process)、if语句、wait语句、case语句和loop语句的使用,指出它们在VHDL设计中的重要性。最后,给出了D触发器和伪双端口RAM模块的实现示例。

1.并发代码

VHDL代码按照执行顺序可以分为并发代码和顺序代码,即并行与串行

并发描述语句有when和generate,此外,仅包含and,not,+,*和sll等操作符的赋值语句也是并发执行的。在块(block)中的代码也是并发执行的

1.1when语句

when语句分为when/else(又称simple when)和when/select/when(又称select when)两种

--when/else
assignment when condition else
assignment when condition else
...;

--when/select/when
assignment when value,
assignment when value,
...;


--例
--when/else
outp <= "000" when (inp = '0' or reset = '1') else
        "001" when ctl ='1' else
        "010";
        
--when/select/when
--当使用with/select/when时,必须对所有可能出现的条件(condition)予以考虑,所以常使用关键字others。
with control select
    output <= "000" when reset,
        "111" when set,
        unaffected when others;    --如果在某些条件出现时不需要进行任何操作,可以使用UNAFFECTED
        
--当需要对多种情况进行判断时,when value的描述方式包括以下3种
when value    --针对单个值进行判断
when value1 to value2    --针对取值范围进行判断,使用枚举类型
when value1 | value2 | ...    --针对多个值进行判断

1.2generate语句

generate是另一种基本的并发现描述语句,它和顺序描述语句中的loop语句一样用于循环执行某项操作,通常与for一起使用

语法结构

--for/generate
label: for identifier in range generate
    (condition, assignment)
end generate

--if/generate
--if/generate不允许使用else,可以与for/generate嵌套使用
label1: for idnetifier in range generate
    ...
    label2: if condition generate
        (condition assignment)
    end generate;
    ...
end generate;

--例
signal x: bit_vector(7 downto 0);
signal y: bit_vector(15 downto 0);
signal z: bit_vector(7 downto 0);
...
g1: for i in x'range generate
    z(i) <= x(i) and y (i+8);
end generate

generate中循环的上界和下界必须是静态的,如果上界或下界中的参数是非静态的,那么代码通常不可综合

1.3块语句

块语句分为简单块(simple block)和卫式块(guarded block)

simple block

simple block仅仅是一种对原有代码进行区域分割的方式

----------法结构如下----------
label: block
    [declarative part]
begin
    (concurrent statement)
end block label;


----------一个完整的block----------
b1: block
    signal a: std_logic;
begin
    a <= input_sig when ena = '1' else 'z';
end block b1;


----------利用block对构造体进行规整----------
architecture example ...
begin
    ...
    block1: block
    begin
        ...
    end block block1;
    ...
    block2: block
    begin
        ...
    end block block2;
    ...
end example;


----------simple block 与 guarded block可以相互嵌套----------
label1: block
    [顶层block部分声明]
begin
    (顶层block并发描述语言)
label2:block
    [嵌套block部分声明]
begin
    (嵌套block并发描述语言)
end block label2;
    (顶层block其他并发描述语言)
end block label2;

guarded block

guarded block 与simple block 相比,多了一个卫式表达式。只有当卫式表达式值为真时,在guarded block中前面有关键词guarded的语句才会执行

语法结构如下

label: block(卫式表达式)
    [声明部分]
begin
    (卫式语句和其他并发描述语句)
end block label;

2.顺序代码

VHDL本质都是并发执行的代码,但是在PROCESS,FUNCTION和PROCEDURE内部的代码都是顺序执行的。当作为一个整体时,他们与外部的其他代码之间又都是并发执行的。

变量只能在顺序代码中使用,相对于信号而言,变量只能时局部的,所以他的值不能传递到process,function和procedure外部

2.1进程

进程(process)内部的语句是一种顺序描述语句,其内部经常使用if,wait,case或loop语句。

process具有敏感信号列表(sencitivity list),或者使用wait语句进行执行条件的判断。process必须包含在主代码段,当敏感信号列表中某个信号发生变化时(或当wait条件语句得到满足时),process内部代码就顺序执行一次。其语法结构如下

[label:]process (sensitivity list)
    [variable name: type [range][:= initial_value;]]
begin
    (顺序执行的代码)
end process [label];

其中变量声明部分是可选的,如果要process内部使用变量,则必须在关键字begin之前的变量声明部分对其进行定义。变量的初始值是不可综合的,只是在仿真过程中使用。

label也是可选的,使用label可增加代码的可读性。

2.2信号和变量

为了方便理解后面的内容,这里补充一点信号与变量的知识,信号与变量详细的讲解会在之后发布

在VHDL中,有两种方法进行动态的数值传递:信号和变量。其中,信号可以在package,entity和architecture中声明,而变量只能在一段顺序描述的代码中声明(比如在process内部进行信号声明)。因此,信号通常是全局的,而变量通常是局部的。

变量的值无法传递到process外的,如果需要进行变量值的传递,必须先把这个值赋给一个信号,然后由该信号将值传递到process外部。赋予变量的值是立即生效的,在此后的代码中,此变量将使用新的变量值。这一点和process中使用的信号不同,新的信号值通常只有在整个process运行完毕以后才开始生效。

2.3if语句

语法结构

if condition then assignments;
elsif conditions then assifnments;
...
else assignments;
end if;


--例
if (x<y) then temp := "11111111";
elsif (x=y and w='0') then temp := "11110000";
else temp := (other => '0');
end if;

2.4wait语句

如果process中使用了wait语句,就不能在使用敏感信号列表了。语法结构如下

--直到信号条件(signal_condition)满足时才进行后面的操作
--在使用wait until时,由于process没有敏感信号列表,所以它必须时process中的第一条语句
wait until signal_condition;
--当后面列出的信号有一个发生变化时,开始进行后面的操作
wait on [signal1,signal2,...];
--等待time所确定的时间后才开始进行后面的操作
wait for time;


--例
process    --没有敏感信号列表
begin
    wait until (clk'event and clk = '1');
    if (rst = '1') then
        output <= "00000000";
    elsif (clk'event and clk = '1')then
        output <=input;
    end if;
end process;

2.5case语句

语法结构

case 表达式 is
    when 条件表达式 => 顺序执行语句;
    when 条件表达式 => 顺序执行语句;
    ...
end case;


--例
case control is
    when"00" => x <= a; y <= b;
    when"01" => NULL;    --等同于unaffected,表示没有任何操作
    when others => x <= "0000"; y <= "zzzz";
end case;

case语句允许在每个测试条件下执行多个赋值操作,而when语句只允许执行一个赋值操作

case与when语句对比

when

case

代码类型

并发代码

顺序代码

用法

在process,function和procedures外使用

在process,function和procedures内使用

必须列出所有可能的组合

是(对with/select/when来说)

是

每个判断分支允许的最大赋值操作数量

1

任意

没有操作动作时使用的关键字

unaffected

null

--下面两端代码实现了同样的功能
--when语句
with sel select
    x <= a when "000";
         b when "001";
         c when "010";
         unaffected when others;
         

--case语句
case sel is 
    when "000" => x <= a;
    when "001" => x <= b;
    when "100" => x <= c;
    when others => null;
end case

2.6loop语句

语法结构

--for/loop,循环固定次数
--与generate语句相似,for/loop语句中上下界必须是静态值,否则可能不可综合
[label:] for 循环变量 in 范围 loop
    (顺序描述语句)
end loop [label];

--while/loop,循环执行直到条件不再满足
[label:] while 条件表达式 loop
    (顺序描述语句)
end loop [label];

--exit,结束整个循环
[label:] exit [label] [when条件表达式];

--next,跳出本次循环
[label:] next [loop_label] [when条件表达式];


--例
 for i in 0 to 5 loop
     x(i) <= enable and w(i+2);
     y(0,i) <= w(i);
 end loop;

 3.实例

3.1用guard block实现D触发器

用guard block实现一个带复位,上升沿触发的D触发器

library ieee;
use ieee.std_logic_1164.all;

entity dff is
    port(d,clk,rst: in std_logic;
        q: out std_logic);
end dff;

architecture dff of dff is
begin
    b1: bolck(clk'event and clk = '1')
    begin
        q <= guard '0' when rst = '1' else d;    //卫式语句,当卫士表达式位真,即rst为1时,q输出0,负责输出d值。
    end block b1;
end dff;

3.2RAM模块

下面代码实现一个简易伪双端口RAM模块

library ieee;
use ieee.std_logic_1164.all;

entity ram is 
    generic(bits: integer := 8;
            words: integer := 16);
    port(wr_ena,clk; in std_logic;
         addr: in integer range 0 to words-1;
         data_in: in std_logic_vector(bits-1 downto 0);
         data_out: out std_logic_vector(bits-1 downto 0));
end ram;
 
architecture ram of ram is 
    type vector_array is array(0 to words-1) of std_logic_vector(bits-1 downto 0);
    signal memory: vector_array;
begin
    process (clk,wr_ena)
    begin
        if(wr_ena = '1')then
            if(clk'event and clk = '1')then
                memory(addr) <= data_in;
            end if;
        end if
    end process;
    data_out <= memory(addr);
end ram;

VHDL常用语法 最后,END IF;值得注意的是,在VHDL中,process并不是一个并发语句,它并不会自动创建一个新的进程。例如,假设我们有一个名为clk的标准逻辑信号和一个名为rst的标准逻辑信号,我们想根据这两个信号的状态来设置一个名为q的标准逻辑信号。有以下九种状态:‘U’(未初始化),‘X’(不确定),‘0’(0),‘1’(1),‘Z’(高阻),‘W’(弱信号不确定),‘L’(弱信号0),‘H’(弱信号1),‘-’(不可能的情况)例如,如果a的值为’0’,b的值为’1’,那么a xor b的结果就是’1’。 阅读详情

相关推荐

使用VHDL实现组合逻辑电路的实践教程

通过VHDL语言深入掌握组合逻辑电路的设计方法,结合实际案例讲解编码技巧与仿真验证流程,帮助开发者高效构建稳定可靠的数字系统。

weixin_35728286的博客 441

VHDL的并行语句

并行语句是硬件描述语言的一大特点,与像c语言不同的是,并行语句的执行是并行的,不会因为书写顺序的前后而产生执行时的先后。VHDL语言支持的并行语句主要有以下7种: 端口映射语句 信号赋值语句 when条件选择语句 generate语句 进程语句 过程调用语句 块语句 并行语句在VHDL程序中的位置 并行语句可以是结构体的begin与end之间的任何位置,举例如下: architecture <arch_name> of <entity_name> is -- Declarat

qhs的博客 1万+

通俗解释VHDL中的并行与串行语句

通过实例解析VHDL中并行与串行语句的执行机制,帮助掌握vhdl程序设计的核心逻辑,厘清代码结构在硬件行为中的真实映射。

weixin_34620658的博客 861

【SpinalHDL快速入门】6.2、SpinalHDL语法之When/Switch/Mux

【SpinalHDL快速入门】6.2、SpinalHDL语法之When/Switch/Mux

悟已往之不谏 知来者之可追 2496

基于VHDL语言、状态机的序列信号发生器的实现

文章目录一、实验平台二、实验描述三、相关代码1、主代码2、仿真文件(testbench)3、分频相关代码三、仿真结果 一、实验平台 1、Basys3开发板; 2、Vivado2017.4开发环境; 3、VHDL语言。 二、实验描述 最近在学习时序电路,接触到状态机,就利用有限状态机,写了一个8位的序列信号发生器(11010010),分为串行输出和并行输出。这次只是仿真,所以没有进行分频,不过我会把...

zero_hero_he的博客 7266

VHDL实现串行与并行加法器项目

VHDL(VHSIC Hardware Description Language)是一种用于描述电子系统硬件功能、结构和行为的硬件描述语言。自1983年被美国国防部提出以来,VHDL已成为电子设计自动化(EDA)领域内的重要工具之一。它的应用不仅限于数字电路的模拟与仿真,还包括FPGA和ASIC的前端设计。在VHDL(VHSIC Hardware Description Language)中,实体(entity)是硬件组件的抽象表示,可以被视作一个模块的接口规范。

weixin_42612804的博客 971

并行到串行和串行到并行转换器VHDL代码Quartus仿真

该项目将涉及 VHDL 中并行到串行和串行到并行转换器的开发和仿真。数字系统通常会获取并行字节的数据,并通过单根导线传输它们,以节省导线面积,减少串扰影响,提高时钟速度或保持设备之间的兼容性。该练习将介绍组件实例化以及在单个项目中使用多个 VHDL 模块文件。在 VHDL 中设计复杂的系统时,优良作法是将系统的功能块分布在多个 VHDL 模块上,从而增加了代码的易用性和功能。整个系统的示意图如图 1 所示。该图的不同 VHDL 模块,实体,组件,端口和信号起初可能会造混淆,因此在开始练习之前了解层次结构非常

xiakunpei123的博客 1800

VHDL中EDA寄存器模块的设计与应用

在现代电子工程领域,电子设计自动化(EDA)已经成为不可或缺的一部分,它利用计算机辅助设计(CAD)技术极大提升了设计效率和质量。EDA的应用贯穿于整个电子系统的设计周期,包括电路设计、版图布局、仿真验证等多个阶段。本章将概述EDA的概念、发展历史和当前应用现状,为读者构建起对EDA技术基础的认知。电子设计自动化是一系列软件工具的集合,这些工具帮助工程师通过电子计算机完成复杂电路的创建、测试和修正过程。它的出现,极大地缩短了产品从设计到上市的周期,降低了研发成本。

weixin_35871529的博客 851

串行和并行转换器的开发设计VHDL代码Quartus仿真

该项目将涉及VHDL中并行到串行和串行到并行转换器的开发和仿真。数字系统通常获取并行字节的数据,并通过单根导线传输它们,以节省导线面积,减少串扰效应,提高时钟速度或保持设备之间的兼容性。该练习将介绍组件实例化以及在单个项目中使用多个VHDL模块文件。在VHDL中设计复杂的系统时,优良作法是将系统的功能块分布在多个VHDL模块上,从而增加了代码的易用性和功能性。

diaojiangxue的博客 830

基于VHDL的通用移位寄存器设计项目解析

移位寄存器是数字电路中的基础组件之一,广泛应用于数据存储、时序控制、数据处理等领域。它们能够按照一定顺序存储并转移数据位,是实现数据并行到串行或串行到并行转换的核心元件。VHDL中的进程(process)是一种行为描述结构,它包含了一组顺序执行的语句,这些语句在仿真或硬件实现中是并发执行的。进程的语句序列能够在特定的信号变化时被触发,这使得进程成为了实现状态机、算法等复杂逻辑的理想选择。串行数据传输是指数据一位接一位地顺序传输,每次只有一个数据位在通信介质上移动。

weixin_32456485的博客 925

四输入卷积操作的VHDL/FPGA/Verilog设计实现

VHDL(VHSIC Hardware Description Language)和Verilog是当今数字设计领域中使用的两种主流硬件描述语言。VHDL起源于1980年代的美国国防部,被设计为一种强类型的、可以描述非常复杂系统的硬件语言。其特点是拥有严格的语法规则,适合编写大型、复杂的设计项目。Verilog最初在1984年由Gateway Design Automation公司开发,作为一种仿真工具的语言出现,后来发展为硬件描述语言。

weixin_33562004的博客 836

并行转串行 串行转并行输出模块

并行转串行 串行转并行输出模块 夏宇闻Verilog 第15章学习笔记 通信协议:scl为高,sda由高跳变低,start;scl为高,sda由低跳变为高,stop;scl为低,sda数据位才能变化 两个模块ptosda和out16hi,将ptosda并转串模块的串行输出给out16hi串转并模块,输出对应的高位电平 代码如下 //************************并行数据转一种...

weixin_43067657的博客 1万+

AI原生应用在UGC内容审核中的实战经验

AI原生应用(AI-Native Application)——以机器学习模型为核心驱动力,深度整合数据、算法、工程架构的完整系统——为破解这一三角难题提供了全新范式。全链路数据驱动:从数据采集、模型训练到决策优化,形成闭环自治系统,无需人工规则干预多模态深度理解:同时处理文本、图像、音频、视频等多类型内容,理解语义而非简单匹配特征自适应进化能力:通过人机协同反馈持续学习新型违规模式,模型周级迭代成为常态审核效率提升300%:单条视频审核耗时从2.3秒降至0.7秒。

AI算力网络与通信的博客 1149

全串行、并行FIR滤波器

全串行FIR实现 `timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Create Date: 2021/03/13 17:28:28 // Design Name: FIR滤波器全串行结构实现仿真 // Module Name: FIR_FULL_SERIAL //////////////////////////////////////////

Kiss丶小坏 3522

AUTOSAR BswM配置实战:手把手教你用Vector Davinci Configurator搭建第一个模式管理规则

本文详细介绍了如何使用Vector Davinci Configurator工具配置AUTOSAR BswM模块,实现车身控制ECU的模式管理规则。通过实战案例,从环境准备、核心概念梳理到具体配置步骤,包括ModeRequestPort、ModeCondition、Logical Expression和Rules的构建,帮助工程师快速掌握BswM配置技巧,提升汽车电子软件开发效率。

weixin_28678831的博客 351

物理与工程中的‘黑话’:Kronecker delta和Levi-Civita符号到底简化了什么?

本文深入解析了物理与工程中常用的Kronecker delta和Levi-Civita符号的简化作用。通过对比传统表示与张量表示,展示了这些符号在向量运算、矩阵迹计算及流体力学模拟中的高效应用,显著提升计算效率和代码可读性。特别适合理论物理和工程数学领域的学习者与从业者。

weixin_27215403的博客 397

8086接口缓存与同步串行发送 VHDL ModelSim

8086接口缓存与同步串行发送 VHDL ModelSim8086接口缓存与同步串行发送 VHDL ModelSim(文末获取)ModelSimVHDL该工程实现一个带缓冲的串行发送模块:外部以8086兼容的片选/读写/地址信号写入8位数据,模块内部用环形缓冲区存储数据;在同步信号FS到来时,若缓冲区累计数据达到阈值,则按固定节拍把若干字节从高位到低位串行输出到TXD;若数据不足,则输出空闲字节用于占位,保证链路连续性。

xiakunpei123的博客 843

手把手教你用STM32F303和LAN9252搭建EtherCAT从站(附IO/AD/DA完整代码)

本文详细介绍了如何使用STM32F303和LAN9252搭建EtherCAT从站,涵盖硬件选型、开发环境配置、协议栈移植及IO/AD/DA功能实现。通过实战指南和完整代码,帮助开发者快速掌握工业自动化中的实时通信技术,提升系统性能与可靠性。

weixin_26802933的博客 235

基于VHDL语言八位加法器设计

基于VHDL八位加法器设计 设计思路 ​ 加法器是数字系统中的基本逻辑器件,减法器和硬件乘法器都可由加法器来构成。多位加法器的构成有两种方式:并行进位和串行进位。并行进位加法器设有进位产生逻辑,运算速度较快;串行进位方式是将全加器级联构成多位加法器。 ​ 并行进位加法器通常比串行级联加法器占用更多的资源。随着位数的增加,相同位数的并行加法器与串行加法器的资源占用差距也越来越大。因此,在工程中使用加法器时,要在速度和容量之间寻找平衡点。 ​ 实践证明,4位二进制并行加法器和串行级联加法器占用几乎相同的资源。这

俯κǎń迗倥 1万+

【目标跟踪】基于Kalman滤波实现无人机运动轨迹跟踪附matlab代码

1 简介 在近代控制中,需要对某一特定的运动目标进行跟踪监测,并需要对其下一时间的运动位置,运动方向,速度等信息进行预先估算,才能达到对目标的即时控制.本文简要讨论了用卡尔曼滤波算法对单个目标航迹进行预测,并借助于Matlab仿真工具,对实验的效果进行评估. 2 部分代码 clc; close all; %initial state xo=25; vox=2; %Observations **** % X-Direction Calcula

qq_59747472的博客 4731

点云体积计算方法之一 附python代码

另外需要注意,这个只适合点云密集分布的场景来计算体积,比如树木扫描的体积;如果只是有表面积扫描的点云,该方法就不能计算整个物体的体积了。通过计算点云所占用的体素的数量来计算点云的近似体积。这是一个非常粗略的近似值,对于复杂的形状可能不准确。

三维点云技术探索 1886

FPGA之道(38)VHDL与Verilog的比较

VHDL相对于Verilog HDL,给人最深刻的印象便是臃肿,掌握起来比较难。 本文摘自《FPGA之道》,学会站在巨人的肩膀上来对比学习二者。

Reborn Lee 1万+

2026保姆级:1小时搞定C# OPC UA客户端开发——PLC与上位机全量数据交互零基础教程

本文介绍了使用C#开发OPC UA客户端的核心流程和关键代码实现。文章首先指出工业上位机开发中OPC UA的重要性,并针对新手常见问题提出了1小时掌握核心功能的解决方案。重点内容包括:选择官方.NET Standard库的优势、5分钟搭建开发环境的步骤、OPC UA客户端架构与通信流程的图解说明,以及完整的客户端基础类代码实现,涵盖了连接管理、证书配置、安全认证等关键功能。通过本文提供的代码模板,开发者可快速实现与PLC等工业设备的稳定数据交互。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 793

并串转换器和串并转换器VHDL代码Quartus仿真

代码功能: 本项目将涉及VHDL中并行到串行和串行到并行转换器的开发和仿真。数字系统通常采用并行字节的数据,并通过一根传输,以节省线面积,减少串扰影响,提高时钟速度,或保持设备之间的兼容性。本练习将介绍组件实例化和在单个项目中使用多个VHDL模块文件。在VHDL中设计复杂的系统时,通过几个VHDL模块传播系统的功能块是很好和常见的做法,从而增加代码的简易性和功能性。

xiakunpei123的博客 1192

使用 YOLO26 的牙科全景X光片分析:从牙齿检测到疾病诊断

从数据预处理自动化、模型架构针对性优化到基于视觉特征的性能分析。它证明了在医学图像分析中,模型架构的进步(如YOLO26的特性)可以有效缓解数据不平衡和目标微小的问题,为临床自动化诊断提供了一个高效、可靠的解决方案。Python"""全局配置模块包含数据集路径、类别名称、论文复现参数、划分比例等常量"""import os# ==================== 路径配置 ====================

u012133341的博客 102

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

上一篇: VHDL语法入门 (三) 运算操作符与属性
下一篇: VHDL语法入门 (五) 信号与变量
EfunStudy
博客等级 码龄5年 184粉丝 31原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值