【verilog】如何一小时成为verilog高手(并非

xjtuse版面向bzhang的verilog学习


感谢来自同学推荐的一个 verilog oj .

(真是一款非常好玩的oj,使我枯燥的verilog半日速通学习变得有趣了起来。欢迎大家来玩!!)

(md没有verilog高亮......typst都有,不亏是typst,库太强大了

assign

assign 赋值目标 = 表达式

赋值目标必须是wire型。

连续赋值语句 assign 描述的是事物之间的关联,而不是将值从一个事物复制到另一个事物的操作。因此当代码中存在多个 assign 时,它们出现的顺序无关紧要。

复制代码
module top_module( output one );
    assign one = 1;
endmodule

不赋值默认为0.

复制代码
module top_module(
    output zero
);
endmodule

运算

c 复制代码
+ - * /
**   // 幂 (同python
&& || !   // 与 或 非 (同c
& | ~   // 按位与 按位或 按位非 (同c
^ ~^   // 异或 同或
<< <<< >> >>>    // 左移 算术左移 右移 算术右移
== !=    // 等于 不等于
=== !==   // 恒等于 恒不等于

缩减运算符 & | ^ 的使用:

实现四位输入的与 或 异或门

复制代码
module top_module( 
    input [3:0] in,
    output out_and,
    output out_or,
    output out_xor
);

    // &in 等价于 in[3] & in[2] & in[1] & in[0]
    assign out_and = &in;
    
    // |in 等价于 in[3] | in[2] | in[1] | in[0]
    assign out_or  = |in;
    
    // ^in 等价于 in[3] ^ in[2] ^ in[1] ^ in[0]
    assign out_xor = ^in;

endmodule

实用的连接运算符 {}:

复制代码
{3'b111, 3'b000} => 6'b111000
{1'b1, 1'b0, 3'b101} => 5'b10101
{4'ha, 4'd10} => 8'b10101010 // 4'ha 和 4'd10 的二进制表示均为 4'b1010

{5{1'b1}} // 5'b11111(或 5'd31 或 5'h1f)
{2{a,b,c}} // 等同于 {a,b,c,a,b,c}
{3'd5, {2{3'd6}}} // 9'b101_110_110。它是 101 与 的连接。
                    // 第二个向量,即 3'b110 的两个副本。

assign {out[7:0], out[15:8]} = in; // 交换两个字节。左右两边都是 16 位向量。
assign out[15:0] = {in[7:0], in[15:8]}; // 这是同一件事。
assign out = {in[7:0], in[15:8]}; // 这有所不同。右侧的 16 位向量被扩展为
                                        // 与左侧的 24 位向量匹配,因此 out[23:16] 为零。
                                        // 在前两个示例中,out[23:16] 没有被赋值。

一些写法

Verilog 支持的 4 种进制简写

完整的格式是:<位宽>'<进制><数值>。

简写 英文全称 中文含义 允许的字符 示例
'b 或 'B Binary 2 进制 0, 1, x, z 4'b1010
'h 或 'H Hexadecimal 16 进制 0-9, a-f, x, z 4'ha (等同于 4'b1010)
'd 或 'D Decimal 10 进制 0-9 4'd10 (等同于 4'b1010)
'o 或 'O Octal 8 进制 0-7, x, z 4'o12 (等同于 4'b1010)
  1. 如果不写进制,默认是 10 进制 :
    如果你写 assign a = 10;,编译器会把它当作 32 位的十进制数 10 处理(32'd10)。
  2. 下划线 _ 增强可读性 :
    可以随意在数字中间加下划线,编译器会忽略它。
    • 16'b1010_1010_1111_0000 比 16'b1010101011110000 容易看多了。
    • 32'hdead_beef 也是合法的。
  3. 特殊值 x 和 z :
    • z:高阻态(悬空,不连线)。
    • x:未知状态(可能是0也可能是1)。
    • 比如:4'b10xz 或 12'h3x0 都是合法的写法。

逻辑值

  • 1:逻辑1
  • 0:逻辑0
  • x:不确定
  • z:高阻态

wire&reg

不声明默认为wire类型,reg需显式标出。

创建一个具有 3 个输入和 4 个输出的模块,使其行为类似于导线,并建立以下连接:

复制代码
a -> w 
b -> x 
b -> y 
c -> z

module top_module( 
    input a,b,c,
    output w,x,y,z );
    assign {w,x,y,z} = {a,b,b,c};
endmodule

可以通过 wire 声明一个中间变量。实现以下示例:

复制代码
`default_nettype none
module top_module(
    input a,
    input b,
    input c,
    input d,
    output out,
    output out_n   ); 
    
    wire N1, N2, N3;
    assign {N1, N2} = {a & b, c & d};
    assign N3 = N1 | N2;
    assign {out ,out_n} = {N3, !N3};

endmodule

`default_nettype none (禁止创建隐式网络)的核心作用是:强迫必须先定义每一个信号,才能使用它。(一般情况下,如果在代码里突然写了一个从来没定义过的名字,编译器默认会把它当作一个 1-bit 的 wire 自动创建出来。)

复制代码
module top_module ( 
    input p1a, p1b, p1c, p1d, p1e, p1f,
    output p1y,
    input p2a, p2b, p2c, p2d,
    output p2y );

	wire n1, n2, n3, n4;
    assign {n1, n2, n3, n4} = {p1a&p1c&p1b, p2a&p2b, p1d&p1e&p1f, p2c&p2d};
    assign {p1y, p2y} = {n1|n3, n2|n4};
endmodule

向量

向量用于将相关的信号分组,并使用同一个名称,以便于操作。例如,wire [7:0] w;声明了一个名为w的 8 位向量,其功能等同于 8 条独立的 wire 线。

向量的声明时将维度放在向量名之前,调用的时候放在向量名之后。可以通过下标连续调用一段。

复制代码
wire [99:0] my_vector;    //Declare a 100-element vector
assign out = my_vector[10];  // Part-select one bit out of the vector
assign out_10 = my_vector[9:0];

eg1.

复制代码
module top_module ( 
    input wire [2:0] vec,
    output wire [2:0] outv,
    output wire o2,
    output wire o1,
    output wire o0  ); 
    assign outv[2:0] = vec[2:0];
    assign {o2, o1, o0} = {vec[2], vec[1], vec[0]};
endmodule

assign outv[2:0] = vec[2:0]; 可以直接写成 assign outv = vec;

assign {o2, o1, o0} = {vec[2], vec[1], vec[0]}; 可以直接写成 assign {o2, o1, o0} = vec;

eg2. Build a combinational circuit that splits an input half-word (16 bits, 15:0 ) into lower 7:0 and upper 15:8 bytes.

复制代码
module top_module( 
    input wire [15:0] in,
    output wire [7:0] out_hi,
    output wire [7:0] out_lo );
    assign {out_hi, out_lo} = {in[15:8], in[7:0]};
endmodule

Module

简单的端口连接

将已有模块a 实例化,并连接端口到顶层模块

复制代码
module mod_a ( input in1, input in2, output out );
    // Module body
endmodule

写法一:按名称连接(推荐)

复制代码
module top_module ( input a, input b, output out );

    // 语法:模块名 实例名 ( .端口名(信号名), ... );
    mod_a inst1 ( 
        .in1(a),   // 将外部信号 a 接到子模块端口 in1
        .in2(b),   // 将外部信号 b 接到子模块端口 in2
        .out(out)  // 将外部信号 out 接到子模块端口 out
    );

endmodule

写法二:按位置连接(By Position)

这种写法类似 C 语言函数调用,必须严格按照 mod_a 定义时的端口顺序来写。

复制代码
module top_module ( input a, input b, output out );

    // mod_a 的定义顺序是: in1, in2, out
    // 所以这里的括号里必须依次填入: a, b, out
    mod_a inst1 ( a, b, out );

endmodule

多个模块的端口连接

在 Verilog 的可综合设计中,模块之间的连接必须通过显示定义的信号(wire/reg)来完成。不能像在 C++ 或 Java 类的成员访问那样,直接在一个模块的实例化中去"读取"另一个实例内部的端口信号。

复制代码
module top_module ( input clk, input d, output q );
    wire q1, q2;
    my_dff ins1 (.clk(clk), .d(d), .q(q1));
    my_dff ins2 (.clk(clk), .d(q1), .q(q2));
    my_dff ins3 (.clk(clk), .d(q2), .q(q));
endmodule

always

复制代码
always @(敏感条件信号表)
	各类顺序语句

always中赋值目标必须为reg型。

例如

复制代码
always @(posedge CLK)
	Q=D;

当CLK的上升沿来临的时候,将D的值赋给Q。@代表等待。

posedge 代表上升沿,negedge代表下降沿。如果没写则默认为电平敏感。

case

always 内部可以使用case语句

case类似于c里面的switch

复制代码
case (表达式)
    取值1: 语句1;
    取值2: 语句2;
    取值3: 语句3;
    ...
    ...
    default: 默认语句;
endcase

不要忘记写endcase!!!default可以不写,不过一般建议写。

复制代码
module top_module ( 
   input clk, 
   input [7:0] d, 
   input [1:0] sel, 
   output reg [7:0] q 
);

   wire [7:0] q1,q2,q3;
   my_dff8 ins1 (.clk(clk), .d(d), .q(q1));
   my_dff8 ins2 (.clk(clk), .d(q1), .q(q2));
   my_dff8 ins3 (.clk(clk), .d(q2), .q(q3));
   
   always @(*)
       case(sel)
           2'b00: q=d;
           2'b01: q=q1;
           2'b10: q=q2;
           2'b11: q=q3;
       endcase
endmodule

当sel的值分别为0,1,2,3的时候,q取对应的值。注意case后面没有冒号。

begin-end

当always中有多条赋值语句的时候,要用begin-end包裹起来,作用相当于c里的大括号

阻塞赋值与非阻塞赋值

组合电路常用阻塞赋值,时序电路常用非阻塞赋值,但不是绝对的。不可以在一个always块中同时使用阻塞赋值与非阻塞赋值。

阻塞赋值

复制代码
always @ (A,B)
begin
    M1=A;
    M2=B&M1;
    Q=M1|M2;
end

激活前 :M1=0,M2=0,Q=0
激活后 :

先计算A=1,马上赋值给M1

再计算B&M1=1,马上赋值给M2

再计算M1|M2=1,马上赋值给Q

非阻塞赋值

复制代码
always @ (A,B)
begin
    M1<=A;
    M2<=B&M1;
    Q<=M1|M2;
end

激活后执行过程 :

先计算A=1,(等待,不赋值)

再计算B&M1=0,(等待,不赋值)

再计算M1|M2=0,(等待,不赋值)

过程结束

先赋值给M1=1

再赋值给M2=0

再赋值给Q=0


一些例子

Dff D触发器

涉及到时序电路用非阻塞取值

复制代码
module top_module (
    input clk,
    input d,
    output reg q );

    always @(posedge clk)
        q<=d;
endmodule

带有同步复位的D触发器

复制代码
module top_module (
    input clk,
    input reset,            // Synchronous reset
    input [7:0] d,
    output [7:0] q
);
    always @(posedge clk) begin
        if (reset) q<=8'b0;        // 当复位信号为1时 q复位取0 注意位宽8
        else q<=d;
    end

endmodule

带有异步复位的D触发器

(XJTUSE超纲了 不学异步 但是bzhang的皮皮踢上出现了)

同步复位:复位信号像是一个排队的人,必须等到时钟上升沿(posedge clk)到来时,才会被处理。

异步复位:复位信号像是一个特权插队者,只要它变为高电平(areset = 1),电路会立即把输出 q 清零,完全不管时钟在哪。

复制代码
module top_module (
    input clk,
    input areset,   // 高电平有效的异步复位
    input [7:0] d,
    output reg [7:0] q
);

    // 关键点:敏感列表中包含了 clk 的上升沿 OR areset 的上升沿
    always @(posedge clk or posedge areset) begin
        if (areset) begin
            // 只要 areset 变为 1,立即执行这里,不看 clk
            q <= 8'b0;
        end
        else begin
            // 只有当 clk 上升沿到达,且 areset 为 0 时,才执行这里
            q <= d;
        end
    end

endmodule

计数器

Build a 4-bit binary counter that counts from 0 through 15, inclusive, with a period of 16. The reset input is synchronous, and should reset the counter to 0.

复制代码
module top_module (
    input clk,
    input reset,      // Synchronous active-high reset
    output [3:0] q);
    always @(posedge clk) begin
        if (reset) q <= 4'b0;
        else q <= q + 1'b1;   // 加到16溢出了会自动复位 所以不用写额外逻辑
    end
endmodule

用16位全加器实现32位全加器

add16按照下图所示连接各个模块。提供的模块add16具有以下声明:

module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );

在每个模块内部add16,会实例化 16 个全加器(模块add1未提供)来实际执行加法运算。您必须编写包含以下声明的全加器模块:

module add1 ( input a, input b, input cin, output sum, output cout );

注意wire的拆分与连接

复制代码
module top_module (
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire [15:0] s1, s2;
    wire c;
    add16 add16_1 (.a(a[15:0]), .b(b[15:0]), .sum(s1), .cout(c));
    add16 add16_2 (.a(a[31:16]), .b(b[31:16]), .cin(c), .sum(s2));
    assign sum =  {s2,s1};
endmodule

module add1 ( input a, input b, input cin,   output sum, output cout );

	assign sum = a^b^cin;
	assign cout = (a&b) | (a&cin) | (b&cin);
	// 呃其实完全没必要这么写 直接 assign {cout, sum} = {a+b+cin}; 就好了
endmodule

以下例子为真题或ppt出现过的

实现一个四位两输入的加法器(前年真题)

这题verilog太容易了 正文一行解决

复制代码
module top_module (
    input [3:0] a,      // 第一个 4 位输入
    input [3:0] b,      // 第二个 4 位输入
    output [3:0] sum,   // 4 位和输出
    output cout         // 进位输出
);

    // 使用拼接运算符 {cout, sum} 来接收 5 位的加法结果
    // 第 4 位(最高位)赋值给 cout,低 4 位赋值给 sum
    assign {cout, sum} = a + b;

endmodule

用一些2-4译码器实现一个4-16译码器(前年真题)

感觉这题还是电路图画比较好

复制代码
// 2-4 译码器子模块
module dec2_4 (
    input [1:0] in,
    input enable,
    output reg [3:0] out
);
    always @(*) begin
        if (enable) begin
            case (in)
                2'b00: out = 4'b0001;
                2'b01: out = 4'b0010;
                2'b10: out = 4'b0100;
                2'b11: out = 4'b1000;
                default: out = 4'b0000;
            endcase
        end else begin
            out = 4'b0000; // 不使能时,输出全 0
        end
    end
endmodule

// 顶层模块 4-16译码器
module dec4_16 (
    input [3:0] in,
    input enable,       // 整个 4-16 译码器的总使能
    output [15:0] out
);
    wire [3:0] select; // 用于连接第一级和第二级的使能信号

    // 第一级:控制层(处理高两位 in[3:2])
    // 根据高两位决定哪一个第二级译码器被激活
    dec2_4 master_dec (
        .in(in[3:2]),
        .enable(enable),
        .out(select)
    );

    // 第二级:输出层(处理低两位 in[1:0])
    // 译码输出 0-3
    dec2_4 slave_dec0 (
        .in(in[1:0]),
        .enable(select[0]),
        .out(out[3:0])
    );

    // 译码输出 4-7
    dec2_4 slave_dec1 (
        .in(in[1:0]),
        .enable(select[1]),
        .out(out[7:4])
    );

    // 译码输出 8-11
    dec2_4 slave_dec2 (
        .in(in[1:0]),
        .enable(select[2]),
        .out(out[11:8])
    );

    // 译码输出 12-15
    dec2_4 slave_dec3 (
        .in(in[1:0]),
        .enable(select[3]),
        .out(out[15:12])
    );

endmodule

4位优先编码器

四个优先级:r3、r2、r1和r0作为一组4位输入信号,输出是最高优先级的二进制代码

复制代码
module prio_encoder_if(
    input [3:0] r,
    output reg [2:0] y
);
    always @*
        if (r[3]==1'b1)  // 可以写成(r[3])
            y = 3'b100;
        else if (r[2]==1'b1)  // 可以写成(r[2])
            y = 3'b011;
        else if (r[1]==1'b1)  // 可以写成(r[1])
            y = 3'b010;
        else if (r[0]==1'b1)  // 可以写成(r[0])
            y = 3'b001;
        else
            y = 3'b000;
endmodule

2-4译码器

复制代码
module decoder_2_4_if(
    input [1:0] a,
    input en,
    output reg [3:0] y
);
    always @*
        if (en == 1'b0)
            y = 4'b0000;
        else if (a == 2'b00)
            y = 4'b0001;
        else if (a == 2'b01)
            y = 4'b0010;
        else if (a == 2'b10)
            y = 4'b0100;
        else
            y = 4'b1000;
endmodule

2个8位二进制数相乘

核心原理类似于列竖式乘法。

复制代码
module mult_for (
    input [8:1] op0,
    input [8:1] op1,
    output reg [16:1] result
);
    integer i;
    always @*
    begin
        result = 0;
        for(i=1; i<=8; i=i+1)
            if(op1[i])
                result = result + (op0 << (i-1));
    end
endmodule

4选1多路选择器

多路选择器其实就是进阶版的译码器。多一步将译码对应位的值传递输出而已。

复制代码
module mux41_case
(
    input in0, in1, in2, in3,
    input s0, s1,
    output reg out  // out声明为reg类型
);
    always @*
    begin
        case ({s1, s0})
            2'b00: out = in0;
            2'b01: out = in1;
            2'b10: out = in2;
            default: out = in0;
        endcase
    end
endmodule

1位二进制比较器

真值表

in0 in1 gt(in0>in1) eq(in0=in1) lt(in0<in1)
0 0 0 1 0
0 1 0 0 1
1 0 1 0 0
1 1 0 1 0
复制代码
module comp_1
(
input in0,in1,
output reg gt,eq,lt
);
always @*
    begin
        gt = 0;
        eq = 0;
        lt = 0;
        if(in0>in1)
            gt = 1;
        if(in0==in1)
            eq = 1;
        if(in0<in1)
            lt = 1;
    end
endmodule

always块内if语句之前,对gt,eq和lt都初始化赋值为0 。

这样做的重要性是保证每个输出都被分配一个值。如果没有这样做,Verilog会认为你不想让它们的值改变,系统将会自动生成一个锁存器,那么得到的电路就不再是一个组合电路了。

8-3 优先编码器

复制代码
module prio_encode_8_3
(
    input [7:0] in,
    output reg [2:0] encode_out
);
    always @*
    begin
        casez (in)
            8'b1???????: encode_out = 3'b000;
            8'b01??????: encode_out = 3'b001;
            8'b001?????: encode_out = 3'b010;
            8'b0001????: encode_out = 3'b011;
            8'b00001???: encode_out = 3'b100;
            8'b000001??: encode_out = 3'b101;
            8'b0000001?: encode_out = 3'b110;
            8'b00000001: encode_out = 3'b111;
        endcase
    end
endmodule

注意这里用的是casez。? 可以表示无关状态,可以用 z` 表示。

串并转换 8bit -> 32bit (前年真题)

原题:实现一个将串行数据(8bit宽)转换为并行数据(32bit 宽)的电路,功能是将有效输入(en=1)的 8bit 数据合并成 32bit 宽数据后输出,同时输出有效信号1,该电路输入输出信号包括:clk(时钟),rst(复位),en(输入有效),datain(输入数据),dout_en(输出有效),dataout(输出数据)。

涉及移位寄存器。其实就是将输入保存在一个中间值(寄存器),存够32bit就输出(dout_en=1).

复制代码
module s8_to_p32 (
    input wire clk,             // 时钟信号
    input wire rst,             // 复位信号 (高电平有效)
    input wire en,              // 输入有效信号
    input wire [7:0] datain,    // 输入数据 (8bit)
    
    output reg dout_en,         // 输出有效信号
    output reg [31:0] dataout   // 输出数据 (32bit)
);

    // 内部寄存器
    // 用于缓存前3次输入的8bit数据,共24bit。
    // 当然也可以定义为32bit,但逻辑上只需保存前24bit等待最后一次拼接。
    reg [23:0] data_buffer;     
    
    // 计数器,范围 0~3,需要2bit宽
    reg [1:0] cnt;              

    always @(posedge clk or posedge rst) begin
        if (rst) begin
            // 复位状态
            cnt         <= 2'd0;
            data_buffer <= 24'd0;
            dout_en     <= 1'b0;
            dataout     <= 32'd0;
        end 
        else begin
            // 默认拉低输出有效信号 (脉冲)
            dout_en <= 1'b0;

            if (en) begin
                if (cnt == 2'd3) begin
                    // ---- 第4个字节到达 ----
                    // 此时 data_buffer 中已经存了前3个字节
                    // 现在的 datain 是第4个字节
                    
                    dout_en <= 1'b1; // 输出有效
                    
                    // 拼接输出:{第1字节, 第2字节, 第3字节, 当前第4字节}
                    dataout <= {data_buffer, datain};
                    
                    // 计数器归零,准备下一轮
                    cnt <= 2'd0;
                    
                    // data_buffer 在此时其实不需要更新,或者清零均可,
                    // 因为下一轮的第1个字节会覆盖写入最低8位,随后移位。
                    // 为了逻辑统一,这里可以不做操作,或者复位 buffer
                    data_buffer <= 24'd0; 
                end 
                else begin
                    // ---- 第1, 2, 3个字节到达 ----
                    // 计数器累加
                    cnt <= cnt + 1'b1;
                    
                    // 移位逻辑:原有的数据左移8位,新数据补入低8位
                    // data_buffer[23:0] << 8 | datain
                    // 实际上只需保留 buffer 的低16位左移,并拼上新数据
                    data_buffer <= {data_buffer[15:0], datain};
                end
            end
        end
    end
endmodule

在oj上实现仿真

实现一个D触发器。呃写top_module有点麻烦,随便看看得了。

复制代码
module top_module ();
    //=========================================================
    // 1. [修改] 信号定义
    //    规则:输入给子模块的信号定义为 reg,从子模块输出的信号定义为 wire
    //=========================================================
    reg clk = 0;
    reg rst_n = 0; // 复位信号 (举例)
    reg data_in = 0; // 自定义输入 (举例)
    
    wire data_out; // 自定义输出 (举例)

    //=========================================================
    // 2. 时钟生成与波形启动 (通常不需要改)
    //=========================================================
    initial `probe_start;   // 启动波形工具
    always #5 clk = ~clk;   // 产生时钟 (周期=10个单位)
    
    //=========================================================
    // 3. [修改] 实例化你的模块 (DUT - Device Under Test)
    //    把下面的 my_custom_module 换成你写的模块名字
    //    把 .端口(信号) 对应连好
    //=========================================================
    my_custom_module u_dut (
        .clk(clk),
        .rst(rst_n),
        .in(data_in),
        .out(data_out)
    );

    //=========================================================
    // 4. [修改] 添加探针 (Probes)
    //    你想在波形图上看到哪个信号,就在这里加一行
    //=========================================================
    `probe(clk);
    `probe(rst_n);
    `probe(data_in);
    `probe(data_out);

    //=========================================================
    // 5. [修改] 测试流程 (Stimulus)
    //    在这里控制信号的变化,制造测试场景
    //=========================================================
    initial begin
        // --- 初始状态 ---
        rst_n = 0; 
        data_in = 0;
        
        // --- 开始测试 ---
        #10 rst_n = 1;      // 10单位时间后,复位拉高
        
        #10 data_in = 1;    // 又过10单位,输入变1
        #20 data_in = 0;    // 又过20单位,输入变0
        
        $display ("Current time: %0d ps", $time); // 打印时间看看
        
        #50 $finish;        // 结束仿真
    end

endmodule

//---------------------------------------------------------
// 下面这里放你自己的模块代码
//---------------------------------------------------------
module my_custom_module(
    input clk, rst, d,
    output reg q
);
    // 这里写你的逻辑
    always @(posedge clk or negedge rst) begin
        if(!rst) q <= 0;
        else     q <= d;
    end
endmodule
相关推荐
hahaha60168 小时前
3NRD降噪算法FPGA实现8并行度设计
fpga开发
松小白song9 小时前
一次“载电流显示为 0“的排查经历:负值钳位引发的踩坑
fpga开发
yingheceping12 小时前
复旦微FPGA开发板厂商TOP5甄选榜:2026选型参考
fpga开发·fpga
NamoAmitabha12814 小时前
PL 端的 GPIO IP(AXI GPIO)---PS控制----deepseek
fpga开发·zynq--ps
hahaha601618 小时前
3D降噪算法YUV降噪FPGA实现
fpga开发
Hello-FPGA2 天前
基于RFSOC FPGA ZCU216 的CoaXPress 采集demo
fpga开发
9527华安2 天前
FPGA基于ADV7182解码PAL视频,Video Processing Subsystem去隔行,提供6套工程源码和技术支持
fpga开发·音视频·pal·adv7182
hahaha60162 天前
数字图像时域滤波或者3D降噪算法FPGA实现
算法·计算机视觉·fpga开发
GateWorld2 天前
Xilinx 7系列FPGA时钟网络详解
fpga开发·时钟网络·xilinx 7系列
szxinmai主板定制专家2 天前
X86 工控机 vs RK3588 异构主控:AMR 控制器 BOM、散热、长期运维对比
运维·stm32·单片机·嵌入式硬件·fpga开发·am62x