简体   繁体   English

与使用该语言的标准操作相比,用C语言对数字电路建模是否具有任何实际好处?

[英]Does modeling digital circuits in C have any practical benefits as opposed using the language's standard operations?

So I've start looking into digital circuit designs and enlightened to find that almost every operation (that I'm aware of), all derive from 3 logical operations: AND , OR , and NOT . 因此,我开始研究数字电路设计,并发现几乎所有操作(我知道)都源自3个逻辑运算: ANDORNOT As an analogy, these are sort of like subatomic particles to atoms that make up everything else. 作为类推,这些原子就像是构成其他所有原子的亚原子粒子。 Subatomic particles are to logic gate as atoms are to processor instructions. 亚原子粒子成为逻辑门,而原子则成为处理器指令。 If programming in Assembly is like putting atoms together, then programming in C is like putting molecules (and atoms) together. 如果在Assembly中编程就像将原子放在一起,那么在C中编程就像将分子(和原子)放在一起。 Someone PLEASE tell me if I'm off base here. 请有人告诉我我是否要离开这里。

With that said, I'm aware that GCC and most other compilers do a pretty good job optimizing from C to machine code. 话虽如此,我知道GCC和大多数其他编译器在从C到机器码的优化方面做得很好。 Lets assume we are looking at an x386 instruction set. 假设我们正在看一个x386指令集。 If I built an 32-bit full-adder using only $$ , || 如果我仅使用$$来构建32位全加器, || , and ~ , is the compiler smart enough to use existing instructions provided by the processor, or will my full-adder end up being a more bloated, less efficient versions of what's already on the processor. ~~ 是足够聪明的编译器,可以使用处理器提供的现有指令,否则我的全加器最终将成为处理器上已有的东西的更肿,效率更低的版本。

Disclaimer: I started looking into digital circuits in an attempt to start learning assembly, and I'm fair in C. I want to model some of these circuits in C to further my understand of the digital circuits because those are in terms I understand. 免责声明:我开始研究数字电路以尝试学习组装,并且在C语言中很公平。我想在C语言中对其中的一些电路进行建模,以进一步理解数字电路,因为这些是我所理解的术语。 But I don't want to lure myself into the illusion that it will also be efficient code (or any other practical benefits other than learning) when using a simple + will do. 但是我不想引诱自己一种幻觉,即使用简单+会行之有效的代码(或者学习以外的任何其他实际好处)。 And yes, I'm aware that the horrible maintainability of the code would far outweigh any benefit's of this coding "style" may provide. 是的,我知道代码的可怕的可维护性将远远超过此编码“样式”可能提供的任何好处。

A software simulation of a full adder will never be anywhere near as efficient than a full adder built out of logic gates of the same technology as the silicon which runs the software simulation. 完全加法器的软件仿真的效率永远不会比采用与运行软件模拟的芯片具有相同技术的逻辑门构建的完全加法器的效率高。 The number of gates involved in running the simulation will far outstrip the gate count in the hardware adder, and the propagation delays will be significantly longer, especially if you include the I/O processing needed to make the simulation function as a real adder which accepts and produces electronic signals, which means that the code has to read and write actual CPU or peripheral I/O pins. 运行模拟所涉及的门数将远远超过硬件加法器中的门数,并且传播延迟将明显更长,特别是如果您包含使模拟功能成为接受加法器的真实加法器所需的I / O处理并产生电子信号,这意味着代码必须读写实际的CPU或外围I / O引脚。

The above is true even if a crack team of the world's best x86 assembly language coders get together in a conference to design the ideal piece of code to implement a full adder in machine language; 即使由世界上最好的x86汇编语言编码人员组成的精干团队参加会议来设计理想的代码片段以实现机器语言的完整加法器,上述事实也是正确的。 in other words, it doesn't reflect the inability of compilers to optimize C sufficiently well. 换句话说,它没有反映出编译器无法充分良好地优化C。

A software simulation of a logic circuit on a some given computer, however, can be more efficient than a circuit built with some different technology from that computer: specifically, older technology. 但是,在一台给定计算机上对逻辑电路进行软件仿真可能比使用与该计算机不同技术(特别是较旧的技术)构建的电路更有效。 For instance, a program running on a modern, fast microcontroller chip with integrated I/O can likely express a faster adder on its GPIO pins, than something cobbed together out of discrete, through-hole transistors, and it will almost certainly take up less space, and possibly require less current. 例如,在带有集成I / O的现代,快速微控制器芯片上运行的程序,与其在离散,通孔晶体管中组合而成的东西相比,可能在其GPIO引脚上表现出更快的加法器,并且几乎可以肯定它所占用的时间更少空间,并且可能需要较少的电流。

I've always been of mind that building digital circuits is no different than programming in assembly. 我一直牢记,构建数字电路与汇编编程没有什么不同。 I've said before that electronics are like physical opcodes. 我之前曾说过,电子设备就像物理操作码。

To you question of C smart-compiling a logic adder to an ADD instruction.. No, it will not. 关于C语言,将逻辑加法器智能编译到ADD指令的问题。不,它不会。 There are a few exceptions in embedded development such as AVR and avr-gcc with the right optimization flags will turn REGISTER|=1<<bit or REGISTER&=~(1<<bit) and turn those into bit set and clear instructions instead of doing a verbatim Load, Logic, Store. 嵌入式开发中有一些例外,例如AVR和avr-gcc,带有正确的优化标志将把REGISTER|=1<<bitREGISTER&=~(1<<bit)变成位并清除指令,而不是逐字加载,逻辑,存储。

Beyond assemble/opcodes I can't really think of an analogy for higher-level languages to electronics. 除了汇编/操作码之外,我真的无法想到将高级语言与电子产品进行类比的方法。

Although you may use C to describe a digital circuit (in fact, the Verilog HDL has some resembling to C), there's one fundamental thing that you cannot model in plain C: parallelism. 尽管您可以使用C来描述数字电路(实际上,Verilog HDL与C相似),但是您不能在纯C中建模的一个基本要素是:并行性。

If there's anything that belong to digital circuit description is its inherent parallelism in the description itself: functions (modules actually), and even code blocks "execute" in parallel. 如果有任何属于数字电路描述的内容,那么它就是描述本身固有的并行性:函数(实际上是模块),甚至代码块都是并行执行的。

Any ordinary C program describes a sequence of operations over time, and therefore, any attempt to describe a digital operation, unless it is a very trivial one, will be compiled as a sequence of steps, not exploiting the parallelism that digital circuits have by nature. 任何普通的C程序都会描述随时间变化的一系列操作,因此,任何描述数字操作的尝试(除非是非常琐碎的操作)都将被编译为一系列步骤,而不是利用数字电路本质上具有的并行性。

That said, there does exist some HDL (hardware description languages) that are fair close to C. One of them is Handel-C . 也就是说,确实存在一些与C相当接近的HDL(硬件描述语言)。其中之一是Handel-C Handel-C uses syntax borrowed from C, plus some additions to better handle the inherent parallelism present in digital design. Handel-C使用从C借用的语法,加上一些附加功能可以更好地处理数字设计中固有的并行性。

For example: imagine you have to exchange the value of two variables. 例如:假设您必须交换两个变量的值。 The classical solution (besides solutions based in bitwise operations and the like) is: 经典解决方案(除了基于位运算等的解决方案)是:

temp = a;
a = b;
b = temp;

However, when someone is learning computer programming, it's a common mistake to code the above sequence as this: 但是,当有人学习计算机编程时,将上述序列编写为以下代码是一个常见错误:

a = b;
b = a;

Because we think in a variable interchange as a parallel operation: " the value of b is copied to a, meanwhile the value of a is copied to b ". 因为我们将变量互换视为并行操作:“ 将b的值复制到a,同时将a的值复制到b ”。

The funny thing about this approach is that it actually works... if we manage to execute these two assignments in parallel. 这种方法的有趣之处在于,它实际上可以工作……如果我们设法并行执行这两个任务。 Something that is not possible in plain C, but it is in Handel-C: 在普通C中是不可能的,但是在Handel-C中是这样的:

par
{
  a = b;
  b = a;
}

The par statement indicates that each code line is to be "executed" in parallel with respect to the others. par语句指示将相对于其他代码行并行“执行”每个代码行。

In Verilog, the same interchange would be written as this: 在Verilog中,相同的互换将这样编写:

a <= b;
b <= a;

<= is the nonblocking assignment in Verilog: the second line is not "executed" after the first one is finished, but both start at the same time. <=是Verilog中的非阻塞分配:在第一行完成后,第二行未“执行”,而是同时开始。 This sequence is normally found inside a clocked always (sort of a loop that is "executed" every time the clock signal in the sensitivity list changes from 0 to 1 - posedge - or from 1 to 0 - negedge - ). 通常在始终计时的内部找到该序列(每次在灵敏度列表中的时钟信号从0变为1- posedge或从1变为0- negedge ,都会“执行”这样的循环)。

always @(posedge clk) begin
  a <= b;
  b <= a;
end

This means: everytime the clock goes from 0 to 1, interchange the values between a and b . 这意味着:每当clock从0变为1时,在ab之间交换值。

Note that I always quote "executed" when I speak about languages for digital design. 请注意,当我谈论数字设计语言时,我总是引用“执行”。 The code doesn't actually translate into a sequence of operations to be executed by a processor, but the code IS a circuit. 该代码实际上并没有转换为要由处理器执行的一系列操作,但是该代码是电路。 Think of it as a 1D rendering of a 2D schematic, with sentences and operators instead of electronic symbols, and assignments, arguments and "function calls" instead of wires. 可以将其视为2D示意图的1D渲染,用句子和运算符代替电子符号,并用赋值,自变量和“函数调用”代替导线。

If you are familiarized with digital circuits, you will realize that the "always" loop look-alike, is actually translated into this: 如果您熟悉数字电路,您将认识到“总是”循环看起来实际上是这样翻译的:

两个触发器,输出相互连接

Which is something you couldn't do with just translating the same high level description into assembly (unless the ISA of the target processor has some sort of XCHG instruction, which is actually not uncommon, and the code keeps the two variables to be interchanged into CPU registers). 仅将相同的高级描述转换为汇编,就无法做到这一点(除非目标处理器的ISA具有某种XCHG指令,这实际上并不少见,并且代码将两个变量互换为CPU寄存器)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM