这是一个用JavaScript实现的数字电路模拟器项目。
它旨在模拟由硬件设计工具(如Yosys,GitHub仓库在这里)合成的电路,并有一个配套项目yosys2digitaljs,用于将Yosys的输出文件转换为DigitalJS格式。该项目也意在成为一个教学工具,因此可读性和易于检查是项目的首要考虑因素之一。
你可以在线试用。这个网页应用是一个单独的GitHub项目。
你可以通过从NPM安装来在你的项目中使用DigitalJS:
npm install digitaljs
或者你可 以直接使用Webpack打包文件。
要模拟使用JSON输入格式(稍后描述)表示的电路,并将其显示在名为#paper
的div
上,你需要运行以下JavaScript代码(查看运行示例):
// 创建模拟对象 const circuit = new digitaljs.Circuit(input_goes_here); // 在#paper上显示 const paper = circuit.displayOn($('#paper')); // 激活实时模拟 circuit.start();
电路使用JSON表示。顶层对象有三个键:devices
、connectors
和subcircuits
。devices
下是构成电路的所有设备列表,以对象形式表示,其中键是(唯一的内部)设备名称。每个设备都有若干属性,以对象形式表示。一个必需的属性是type
,用于指定设备类型。设备示例:
"dev1": { "type": "And", "label": "AND1" }
connectors
下是设备端口之间的连接列表,以对象数组形式表示,每个对象有两个键:from
和to
。这两个键都映射到一个包含id
和port
两个键的对象;前者对应设备名称,后者对应该设备的有效端口名称。连接必须从输出端口连接到输入端口,且两个端口的位宽必须相等。连接示例:
{ "from": { "id": "dev1", "port": "out" }, "to": { "id": "dev2", "port": "in" } }
subcircuits
下是子电路定义列表,以对象形式表示,其中键是唯一的子电路名称。子电路名称可以用作类型为Subcircuit
的设备的celltype
;这会实例化该子电路。子电路定义遵循整个电路的表示方式,但子电路(目前)不能定义自己的子电路。子电路可以包含Input
和Output
设备,这些设备会映射到子电路实例的端口。
Not
(非门)、Repeater
(中继器)bits
(自然数)in
(bits
位)out
(bits
位)And
(与门)、Nand
(与非门)、Or
(或门)、Nor
(或非门)、Xor
(异或门)、Xnor
(同或门)bits
(自然数)、inputs
(自然数,默认为2)in1
、in2
... inN
(bits
位,N
= inputs
)out
(bits
位)AndReduce
、NandReduce
、OrReduce
、NorReduce
、XorReduce
、XnorReduce
bits
(自然数)in
(bits
位)out
(1位)ShiftLeft
(左移)、ShiftRight
(右移)bits.in1
、bits.in2
和bits.out
(自然数),signed.in1
、signed.in2
、signed.out
和fillx
(布尔值)in1
(bits.in1
位)、in2
(bits.in2
位)out
(bits.out
位)Eq
(等于)、Ne
(不等于)、Lt
(小于)、Le
(小于等于)、Gt
(大于)、Ge
(大于等于)bits.in1
和bits.in2
(自然数),signed.in1
和signed.in2
(布尔值)in1
(bits.in1
位)、in2
(bits.in2
位)out
(1位)Constant
constant
(二进制字符串)out
(constant.length
位)Negation
(取反)、UnaryPlus
(正号)bits.in
和bits.out
(自然数),signed
(布尔值)in
(bits.in
位)out
(bits.out
位)Addition
(加法)、Subtraction
(减法)、Multiplication
(乘法)、Division
(除法)、Modulo
(取模)、Power
(幂运算)bits.in1
、bits.in2
和bits.out
(自然数),signed.in1
和signed.in2
(布尔值)in1
(bits.in1
位)、in2
(bits.in2
位)out
(bits.out
位)Mux
bits.in
、bits.sel
(自然数)in0
... inN
(bits.in
位,N
= 2**bits.sel
-1),sel
(bits.sel
位)out
(bits.in
位)Mux1Hot
bits.in
、bits.sel
(自然数)in0
... inN
(bits.in
位,N
= bits.sel
),sel
(bits.sel
位)out
(bits.in
位)MuxSparse
bits.in
、bits.sel
(自然数),inputs
(自然数列表),default_input
(可选布尔值)in0
... inN
(bits.in
位,N
= inputs.length
,如果default_input
为真则+1)out
(bits.in
位)Dff
bits
(自然数),polarity.clock
、polarity.arst
、polarity.srst
、polarity.aload
、polarity.set
、polarity.clr
、polarity.enable
、enable_srst
(可选布尔值),initial
(可选二进制字符串),arst_value
、srst_value
(可选二进制字符串),no_data
(可选布尔值)in
(bits
位),clk
(1位,如果存在polarity.clock
),arst
(1位,如果存在polarity.arst
),srst
(1位,如果存在polarity.srst
),en
(1位,如果存在polarity.enable
),set
(1位,如果存在polarity.set
),clr
(1位,如果存在polarity.clr
),ain
(bits
位,如果存在polarity.aload
),aload
(1位,如果存在polarity.aload
)out
(bits
位)Memory
bits
、abits
、words
、offset
(自然数),rdports
(读端口描述符数组),wrports
(写端口描述符数组),memdata
(内存内容描述)enable_polarity
、clock_polarity
、arst_polarity
、srst_polarity
(可选布尔值),init_value
、arst_value
、srst_value
(可选二进制字符串),transparent
、collision
(可选布尔值或布尔值数组)enable_polarity
、clock_polarity
、no_bit_enable
(可选布尔值)rdKaddr
(abits
位),rdKen
(1位,如果存在enable_polarity
),rdKclk
(1位,如果存在clock_polarity
),rdKarst
(1位,如果存在arst_polarity
),rdKsrst
(1位,如果存在srst_polarity
)rdKdata
(bits
位)wrKaddr
(abits
位),wrKdata
(bits
位),wrKen
(当no_bit_enable
为真时为1位,否则为bits
位,如果存在enable_polarity
),wrKclk
(1位,如果存在clock_polarity
)Clock
out
(1位)Button
out
(1位)Lamp
in
(1位)NumEntry
bits
(自然数),numbase
(字符串)out
(bits
位)NumDisplay
bits
(自然数),numbase
(字符串)in
(bits
位)Input
bits
(自然数)out
(bits
位)Output
bits
(自然数)in
(bits
位)Display7
bits
(仅8位 - 最高有效位控制小数点LED)BusGroup
groups
(自然数数组)in0
(groups[0]
位) ... inN
(groups[N]
位)out
(groups
总和位)BusUngroup
groups
(自然数数组)in
(groups
总和位)out0
(groups[0]
位) ... outN
(groups[N]
位)BusSlice
slice.first
、slice.count
、slice.total
(自然数)in
(slice.total
位)out
(slice.count
位)ZeroExtend
、SignExtend
extend.input
、extend.output
(自然数)in
(extend.input
位)out
(extend.output
位)FSM
bits.in
、bits.out
、states
、init_state
、current_state
(自然数)、trans_table
(转换描述符数组)ctrl_in
、ctrl_out
(二进制字符串)、state_in
、state_out
(自然数)clk
(1位)、arst
(1位)、in
(bits.in
位)out
(bits.out
位)进一步开发模拟器的一些想法: