uart接口用systemverilog实现

《牛客刷verilog》Part I Verilog快速入门 - 之前刷过HDLbits上面的题目,点击链接可以查看详细笔记:verilog练习:hdlbits网站系列完结! - 最近又想刷一下牛客上面的题目,可以点击链接与小编一起刷题:[牛客刷题] - 小编不才,文中如有不当之处,可以在评论中互相交流。此处题目推荐看牛客的评论区,再提一嘴,注意积累自己的基本功`算法、设计模式、软件等`..................... 阅读详情

1.发送模块

module uart_tx(clk,rst,start,tx_data_in,tx,tx_active,done_tx);

parameter clk_freq = 50000000; //MHz
parameter baud_rate = 19200; //bits per second
input clk,rst;
input start;
input [7:0] tx_data_in;
output tx;
output tx_active;
output logic done_tx;

localparam clock_divide = (clk_freq/baud_rate);//分频

enum bit [2:0]{ tx_IDLE = 3'b000,
                tx_START = 3'b001,
		        tx_DATA = 3'b010,
	            tx_STOP = 3'b011,
		        tx_DONE = 3'b100 } tx_STATE, tx_NEXT;//状态机的五个状态
					 
logic [11:0] clk_div_reg,clk_div_next;//分频计数
logic [7:0] tx_data_reg;//当前发送的数据
logic [7:0] tx_data_next;//下一个发送的数据
logic tx_out_reg;//当前发送的单bit数据
logic tx_out_next;//下一个发送的单bit数据
logic [2:0] index_bit_reg,index_bit_next;//发送bit的索引

assign tx_active = (tx_STATE == tx_DATA);//只有为发送状态时,tx_active==1
assign tx = tx_out_reg;

always_ff @(posedge clk) begin
if(rst) begin
tx_STATE <= tx_IDLE;
clk_div_reg <= 0;
tx_out_reg <= 0;
tx_data_reg <= 0;
index_bit_reg <= 0;
end
else begin
tx_STATE <= tx_NEXT;
clk_div_reg <= clk_div_next;
tx_out_reg <= tx_out_next;
tx_data_reg <= tx_data_next;
index_bit_reg <= index_bit_next;
end
end

always @(*) begin
tx_NEXT = tx_STATE;
clk_div_next = clk_div_reg;
tx_out_next = tx_out_reg;
tx_data_next = tx_data_reg;
index_bit_next = index_bit_reg;
done_tx = 0;

case(tx_STATE)

tx_IDLE: begin
tx_out_next = 1;
clk_div_next = 0;
index_bit_next = 0;
if(start == 1) begin//start=1,开始发送
tx_data_next = tx_data_in;
tx_NEXT = tx_START;
end
else begin
tx_NEXT = tx_IDLE;
end
end

tx_START: begin
tx_out_next = 0;//拉低一个电平,表示起始位
if(clk_div_reg < clock_divide-1) begin
clk_div_next = clk_div_reg + 1'b1;
tx_NEXT = tx_START;
end
else begin
clk_div_next = 0;
tx_NEXT = tx_DATA;
end
end

tx_DATA: begin
tx_out_next = tx_data_reg[index_bit_reg];//开始发送数据位
if(clk_div_reg < clock_divide-1) begin
clk_div_next = clk_div_reg + 1'b1;
tx_NEXT = tx_DATA;
end
else begin
clk_div_next = 0;
if(index_bit_reg < 7) begin
index_bit_next = index_bit_reg + 1'b1;
tx_NEXT = tx_DATA;
end
else begin
index_bit_next = 0;
tx_NEXT = tx_STOP; 
end
end
end

tx_STOP: begin
tx_out_next = 1;//停止位,拉高一个电平
if(clk_div_reg < clock_divide-1) begin
clk_div_next = clk_div_reg + 1'b1;
tx_NEXT = tx_STOP;
end
else begin
clk_div_next = 0;
tx_NEXT = tx_DONE;
end
end

tx_DONE: begin
done_tx = 1;
tx_NEXT = tx_IDLE;
end

default: tx_NEXT = tx_IDLE;
endcase
end

endmodule 

2.接收模块

 

module uart_rx(clk,rst,rx,rx_data_out);

parameter clk_freq = 50000000; //MHz
parameter baud_rate = 19200; //bits per second
input clk;
input rst;
input rx;
output [7:0] rx_data_out;

localparam clock_divide = (clk_freq/baud_rate);

enum bit [2:0] { rx_IDLE = 3'b000,
                 rx_START = 3'b001,
		 rx_DATA = 3'b010,
		 rx_STOP = 3'b011,
		 rx_DONE = 3'b100 } rx_STATE, rx_NEXT;
					 
logic [11:0] clk_div_reg,clk_div_next;//分频计数
logic [7:0] rx_data_reg,rx_data_next;
logic [2:0] index_bit_reg,index_bit_next;//bit索引


always_ff @(posedge clk) begin
if(rst) begin
rx_STATE <= rx_IDLE;
clk_div_reg <= 0;
rx_data_reg <= 0;
index_bit_reg <= 0;
end
else begin
rx_STATE <= rx_NEXT;
clk_div_reg <= clk_div_next;
rx_data_reg <= rx_data_next;
index_bit_reg <= index_bit_next;
end
end

always @(*) begin
rx_NEXT = rx_STATE;
clk_div_next = clk_div_reg;
rx_data_next = rx_data_reg;
index_bit_next = index_bit_reg;

case(rx_STATE)					 

rx_IDLE: begin
clk_div_next = 0;
index_bit_next = 0;
if(rx == 0) begin//接收到低电平,表示接收开始
rx_NEXT = rx_START;
end
else begin
rx_NEXT = rx_IDLE;
end
end

rx_START: begin
if(clk_div_reg == (clock_divide-1)/2) begin
if(rx == 0) begin
clk_div_next = 0;
rx_NEXT = rx_DATA;
end
else begin
rx_NEXT = rx_IDLE;
end
end
else begin
clk_div_next = clk_div_reg + 1'b1;
rx_NEXT = rx_START;
end
end

rx_DATA: begin
if(clk_div_reg < clock_divide-1) begin
clk_div_next = clk_div_reg + 1'b1;
rx_NEXT = rx_DATA;
end
else begin
clk_div_next = 0;
rx_data_next[index_bit_reg] = rx;//接收数据
if(index_bit_reg < 7) begin
index_bit_next = index_bit_reg + 1'b1;
rx_NEXT = rx_DATA;
end
else begin
index_bit_next = 0;
rx_NEXT = rx_STOP;
end
end
end

rx_STOP: begin
if(clk_div_reg < clock_divide - 1) begin
clk_div_next = clk_div_reg + 1'b1;
rx_NEXT = rx_STOP;
end
else begin
clk_div_next = 0;
rx_NEXT = rx_DONE;
end
end

rx_DONE: begin
rx_NEXT = rx_IDLE;
end

default: rx_NEXT = rx_IDLE;
endcase
end

assign rx_data_out = rx_data_reg;

endmodule

3.顶层模块

module uart(clk,rst,rx,tx_data_in,start,rx_data_out,tx,tx_active,done_tx);

parameter clk_freq = 50000000; //MHz
parameter baud_rate = 19200; //bits per second
parameter clock_divide = (clk_freq/baud_rate);

  input clk,rst; 
  input rx;
  input [7:0] tx_data_in;
  input start;
  output tx; 
  output [7:0] rx_data_out;
  output tx_active;
  output done_tx;
	
	
uart_rx 
       #(.clk_freq(clk_freq),
	 .baud_rate(baud_rate)
	)
      receiver
             (
              .clk(clk),
	      .rst(rst),
	      .rx(rx),
	      .rx_data_out(rx_data_out)
             );


uart_tx 
       #(.clk_freq(clk_freq),
	 .baud_rate(baud_rate)
        )
      transmitter			 
               (               
                .clk(clk),
		.rst(rst),
		.start(start),
		.tx_data_in(tx_data_in),
		.tx(tx),
		.tx_active(tx_active),
		.done_tx(done_tx)
               );

endmodule

基于UVM的验证

1.定义接口

interface uart_intf;
  
  logic clk,rst;
  //接收端口
  logic rx;
  logic [7:0] rx_data_out;
  //发送端口
  logic [7:0] tx_data_in;
  logic start;
  logic tx;
  logic tx_active;
  logic done_tx; 

endinterface

2.transaction

`include "uvm_macros.svh"
import uvm_pkg::*;

  class uart_trans extends uvm_sequence_item;
   
  
    `uvm_object_utils(uart_trans)
         
     bit rx;
	 bit [7:0] rx_data_out;
	 bit start;
	 bit tx;
	   
	 rand bit [7:0] tx_data_in;
	 bit tx_active;
	 bit done_tx;
  
   
    function new (string name = "uart_trans");
      super.new(name);
    endfunction
 endclass: uart_trans

3.覆盖率收集

class uart_cov extends uvm_subscriber #(uart_trans);//继承uvm_subscriber,该类自带了一个uvm_analysis_imp analysis_export端口
  
  `uvm_component_utils(uart_cov)
  uart_trans trans;
	

  covergroup cov_inst;//定义覆盖组
  RX:coverpoint trans.rx {option.auto_bin_max = 1;}//定义bin的数量
  TX_DIN:coverpoint trans.tx_data_in {option.auto_bin_max = 8;}
  START:coverpoint trans.start {option.auto_bin_max = 1;}
  TX:coverpoint trans.tx {option.auto_bin_max = 1;}
  RX_DOUT:coverpoint trans.rx_data_out {option.auto_bin_max = 8;}
  TX_ACT:coverpoint trans.tx_active {option.auto_bin_max = 1;}
  DONE:coverpoint trans.done_tx {option.auto_bin_max = 1;}
  
  RXxRX_DOUT: cross RX,RX_DOUT;//交叉覆盖
  TXxTX_DINxTX_ACTxDONE: cross TX,TX_DIN,TX_ACT,DONE;
  STARTxTX_DIN: cross START,TX_DIN;
  endgroup 
  
  
  function new(string name="", uvm_component parent);
		super.new(name, parent);
		cov_inst = new();//创建覆盖组对象
	endfunction

	function void build_phase(uvm_phase phase);
		super.build_phase(phase);
	endfunction


  	virtual function void write(uart_trans t);//在分析imp端口定义write方法
  	$cast(trans, t);
	 cov_inst.sample();
	 endfunction

endclass

4.sequence

typedef uvm_sequencer #(uart_trans) uart_sequencer;//sequencer直接使用uvm_sequencer

class uart_sequence extends uvm_sequence #(uart_trans);
  
    `uvm_object_utils(uart_sequence)
    int count;
    
    function new (string name = ""); 
      super.new(name);
    endfunction

    task body;
      if (starting_phase != null)
        starting_phase.raise_objection(this);
        void'(uvm_config_db #(int)::get(null,"","no_of_transactions",count));
      repeat(count)
      begin
        req = uart_trans::type_id::create("req");//发送item
        start_item(req);
        if( !req.randomize() )
          `uvm_error("", "Randomize failed")
        finish_item(req);
      end
      
      if (starting_phase != null)
        starting_phase.drop_objection(this);
    endtask: body
   
  endclass: uart_sequence

5.driver

class uart_driver extends uvm_driver #(uart_trans);
  
    `uvm_component_utils(uart_driver)

    parameter clk_freq = 50000000; //MHz
    parameter baud_rate = 19200; //bits per second
    localparam clock_divide = (clk_freq/baud_rate);

    virtual uart_intf vif;
    reg [7:0] data;
    int no_transactions;
    
    
    function new(string name, uvm_component parent);
      super.new(name, parent);
    endfunction
    
    virtual function void build_phase(uvm_phase phase);
      // Get interface reference from config database
      if( !uvm_config_db #(virtual uart_intf)::get(this, "", "uart_intf", vif) )//获取虚接口
        `uvm_error("", "uvm_config_db::get failed")
    endfunction 
   
    virtual task void run_phase(uvm_phase phase);
	  super.run_phase(phase);
      forever
      begin
        seq_item_port.get_next_item(req);

        
      `uvm_info("","---------------------------------------------",UVM_MEDIUM) 
      `uvm_info("", $sformatf("\t Transaction No. = %0d",no_transactions),UVM_MEDIUM) 
      //Test tx 验证发送
      vif.start <= 1;
      vif.rx <= 1;
      @(posedge vif.clk);
      vif.tx_data_in <= req.tx_data_in;
      @(posedge vif.clk);
      wait(vif.done_tx == 1);
      vif.start <= 0;
      if(vif.done_tx == 1) begin
      `uvm_info("", $sformatf("\t start = %0b, \t tx_data_in = %0h,\t done_tx = %0b",vif.start,req.tx_data_in,vif.done_tx),UVM_MEDIUM)  
      `uvm_info("","[TRANSACTION]::TX PASS",UVM_MEDIUM)  
       end
      else begin
      `uvm_info("", $sformatf("\t start = %0b, \t tx_data_in = %0h,\t done_tx = %0b",vif.start,req.tx_data_in,vif.done_tx),UVM_MEDIUM)  
      `uvm_info("","[TRANSACTION]::TX PASS",UVM_MEDIUM)  
       end  
      repeat(100) @(posedge vif.clk);
      //Test rx 验证接收
	    @(posedge vif.clk);
	    data = $random;
	    vif.rx <= 1'b0;
	    repeat(clock_divide) @(posedge vif.clk);
	    for(int i=0;i<8;i++) 
		begin
	    vif.rx <= data[i];
	    repeat(clock_divide) @(posedge vif.clk);
	    end
	    vif.rx <= 1'b1;
	    repeat(clock_divide) @(posedge vif.clk);
	    repeat(100) @(posedge vif.clk); 
	   `uvm_info("", $sformatf("\t Expected data = %0h, \t Obtained data = %0h", data,vif.rx_data_out),UVM_MEDIUM)  
      begin
	    if(vif.rx_data_out == data) begin
	    `uvm_info("","[TRANSACTION]::RX PASS",UVM_MEDIUM)  
      `uvm_info("","---------------------------------------------",UVM_MEDIUM)  
       end
	    else begin 
	   `uvm_info("","[TRANSACTION]::RX FAIL",UVM_MEDIUM)  
     `uvm_info("","---------------------------------------------",UVM_MEDIUM)  
      end
  end
                
        seq_item_port.item_done();
        no_transactions++;
      end
    endtask

  endclass: uart_driver

6.monitor

class uart_mon extends uvm_monitor;
	
	virtual uart_intf intf;
	uart_trans trans;
	uvm_analysis_port #(uart_trans) ap_port;//分析端口
	`uvm_component_utils(uart_mon)
	
	function new(string name="", uvm_component parent);
		super.new(name, parent);
	endfunction


	function void build_phase(uvm_phase phase);
	  super.build_phase(phase);
	  ap_port = new("ap_port",this);
	  //trans = uart_trans::type_id::create("trans");
		if(!uvm_config_db #(virtual uart_intf)::get(this, "", "uart_intf", intf)) 
		   begin
		    `uvm_error("ERROR::", "UVM_CONFIG_DB FAILED in uart_mon")
		    end
		//ap_port = new("ap_port", this);
	endfunction

  
  task run_phase(uvm_phase phase);
    super.run_phase(phase);
    while(1) begin
      @(posedge intf.clk);
      trans = uart_trans::type_id::create("trans");
      trans.start = intf.start;
      trans.tx_active = intf.tx_active;
      trans.done_tx = intf.done_tx;
      trans.tx_data_in = intf.tx_data_in;
      trans.rx = intf.rx;
      trans.rx_data_out = intf.rx_data_out;
      trans.tx = intf.tx;
      ap_port.write(trans);
    end
  endtask
  
  
endclass

7.agent

class uart_agent extends uvm_agent;
	
 `uvm_component_utils(uart_agent)
	  
	  uart_sequencer seqr;
    uart_driver    driv;
    uart_mon mon;
    uart_cov cov;
    
    function new(string name = "", uvm_component parent);
      super.new(name, parent);
    endfunction
 
    function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      seqr = uart_sequencer::type_id::create("seqr", this);
      driv = uart_driver::type_id::create("driv", this);
      mon = uart_mon::type_id::create("mon", this);
      cov = uart_cov::type_id::create("cov", this);
    endfunction
    
    function void connect_phase(uvm_phase phase);
      super.connect_phase(phase);
      driv.seq_item_port.connect( seqr.seq_item_export);
      mon.ap_port.connect(cov.analysis_export);//连接monitor和subscriber
    endfunction
    

endclass

 8.environment

class uart_env extends uvm_env;

  `uvm_component_utils(uart_env)
    
   uart_agent agent;
    
    function new(string name = "", uvm_component parent);
      super.new(name, parent);
    endfunction
 
    function void build_phase(uvm_phase phase);
	super.build_phase(phase);
    agent = uart_agent::type_id::create("agent",this);  
    endfunction
    
    
  endclass: uart_env

9.test

class uart_test extends uvm_test;
  
    `uvm_component_utils(uart_test)
    
    uart_env env;
    
    function new(string name = "", uvm_component parent);
      super.new(name, parent);
    endfunction
    
    function void build_phase(uvm_phase phase);
	   super.build_phase(phase);
      env = uart_env::type_id::create("env", this);
    endfunction
    
    	function void end_of_elaboration_phase(uvm_phase phase);
			//`uvm_info(uvm_get_fullname(), this.sprint(), UVM_NONE)
			`uvm_info("", this.sprint(), UVM_NONE)
		endfunction
    
    task run_phase(uvm_phase phase);
      uart_sequence seqr;
      seqr = uart_sequence::type_id::create("seqr");//创建对象并启动sequence
      //if( !seqr.randomize() ) 
        //`uvm_error("", "Randomize failed")
      seqr.starting_phase = phase;
      seqr.start( env.agent.seqr );
    endtask
     
  endclass: uart_test

10.顶层模块

`include "uart_trans.sv"
`include "uart_sequence.sv"
`include "uart_intf.sv"
`include "uart_driver.sv"
`include "uart_mon.sv"
`include "uart_cov.sv"
`include "uart_agent.sv"
`include "uart_env.sv"
`include "uart_test.sv"

module tb_uart_top;
  
  
  bit clk;
  bit rst;
  
  uart_intf intf();
  
  uart    dut(
              .clk(intf.clk),
              .rst(intf.rst),
              .rx(intf.rx),
              .tx_data_in(intf.tx_data_in),
              .start(intf.start),
              .rx_data_out(intf.rx_data_out),
              .tx(intf.tx),
              .tx_active(intf.tx_active),
              .done_tx(intf.done_tx)
              );

  // Clock generator
  initial
  begin
    intf.clk = 0;
    forever #5 intf.clk = ~intf.clk;
  end
  
  initial
  begin
    intf.rst = 1;
    #1000;
    intf.rst = 0;
  end



  initial
  begin
    uvm_config_db #(virtual uart_intf)::set(null, "*", "uart_intf", intf);
    void'(uvm_config_db #(int)::set(null,"*","no_of_transactions",10));
    
    uvm_top.finish_on_completion = 1;
    
    run_test("uart_test");
  end

endmodule: tb_uart_top

 

FPGA:uart原理+tx发送模块+rx接收模块 它在发送数据时将并行数据转换为串行的数据来传输,在接收数据时将接收到的串行数据转换成并行数据。UART串口通信需要两根信号线来实现,一根用于发送,另一个用于接收。串口通信速率用波特率表示,它表示每秒传输二进制数据的位数,单位是bit/s(位/秒),简称bps;tx发送模块:共四个状态,IDLE状态,START状态,DATA状态,FINISH状态。不带时钟同步信号的数据传输,发送方和接收方使用各自的时钟控制数据的发送和接收过程。带时钟同步信号的数据传输,发送方和接收方在同一时钟控制下,同步传输数据。 阅读详情

相关推荐

verilog 编写uart串口代码之接收端(RX)

UART模块可以划分为三个模块:接收端、发送端、以及波特率发生器。 首先我们来介绍接收端的实现: UART整体模块框图包括了RX端和TX端;RX端有 input UART_RXD,output uart_rx_en,output uart_rx_dat[7:0];TX端有 output UART_TXD,input uart_tx_en,inpu...

qq578467144的博客 1410

使用Verilog语言生成7位伪随机码

7位伪随机码的生成

lcococola的博客 2925

(177)SystemVerilog[UART接收]

第一,SystemVerilog简称为SV语言,是一种相当新的语言,它建立在Verilog语言的基础上,是 IEEE 1364 Verilog-2001 标准的扩展增强,兼容Verilog 2001,将硬件描述语言(HDL)与现代的高层级验证语言(HVL)结合了起来,并新近成为下一代硬件设计和验证的语言。第二,SystemVerilog是Verilog语言的拓展和延伸。

m0_46498597的博客 99

【学术相关】学会写伪代码

目录一、伪代码是什么?二、伪代码的语法规则三、伪代码实例一、伪代码是什么?伪代码(Pseudocode)是一种算法描述语言。使用伪代码的目的是为了使被描述的算法可以容易地以任何一种编程语言(C, Java, Pascal)实现。因此,伪代码必须结构清晰,代码简单,可读性好,并且类似自然语言。伪代码的优点提高任何方法的可读性。这是开始实现算法的最佳方法之一。充当程序与算法或流程图之间的桥梁。也可以作...

fengdu78的博客 2万+

(8)UART发送SystemVerilog描述

2.08 UART发送SystemVerilog描述 2.8.1 本节目录 第一,章节目录; 第二,前言; 第三,FPGA简介; 第四,Systemverilog简介; 第五,uart发送Systemverilog描述实例; 第六,结束语。 2.8.2 本节引言 给FPGA一个支点,它可以撬动整个数字逻辑。““给我一根杠杆我就能撬动地球”是古希腊数学家、物理学家阿基米德说的,这句话是阿基米德的经典语录,这句话还被翻译为“给我一个支点,我就能撬起整个地球”,用了夸张的方式来说明杠杆原理。”

kouq123的博客 261

7 SystemVerilog语言编写UART接收

2.07 SystemVerilog语言编写UART接收 2.7.1 本节目录 1)章节目录; 2)FPGA简介; 3)SystemVerilog简介; 4)SystemVerilog语言编写UART接收; 5)本节结束; 2)引言 2.7.2 FPGA简介 FPGA(Field Programmable Gate Array)是在PAL、GAL等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器

m0_46498597的博客 256

用systemverilog写一个UART验证平台

在 SystemVerilog 中写一个 UART 验证平台,你可以这样做: 定义 UART 模块的输入和输出口,包括数据输入输出口、时钟信号、以及控制信号(如读写信号、中断信号等)。 在模块内部实现 UART 协议的相关功能,包括计算校验和、检测帧错误等。 使用 SystemVerilog 的随机化测试功能对 UART 模块进行验证,即使用 randomize 函数生成随机的输入数据,然后...

weixin_35749796的博客 367

8 SystemVerilog语言编写UART发送

2.08 SystemVerilog语言编写UART发送 2.8.1 本节目录 1)章节目录; 2)FPGA简介; 3)SystemVerilog简介; 4)SystemVerilog语言编写UART发送; 5)本节结束; 2.8.2 FPGA简介 FPGA(Field Programmable Gate Array)是在PAL、GAL等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电.

m0_46498597的博客 295

SystemVerilog测试平台设计:新手教程(含实例)

面向systemverilog菜鸟教程的学习者,详解测试平台搭建流程,结合实际案例帮助快速掌握核心技巧,轻松迈入验证开发门槛。

weixin_29138345的博客 503

基于Cyclone IV FPGA的VT220兼容虚拟控制台设计与实现

VT100是整个VT系列中最具有里程碑意义的产品,它首次系统地引入了基于ASCII码的转义控制机制,使得主机可以通过串行链路发送特定字节序列来控制终端的行为,而非仅传输纯文本内容。其核心在于利用ESC字符(ASCII 0x1B)作为“转义起始符”,后接一系列参数和命令字符,形成所谓的“ESC序列”。例如:ESC[A → 光标上移一行ESC[2J → 清除整个屏幕ESC[31m → 设置前景色为红色(ANSI扩展)

weixin_42609225的博客 1065

UART Verilog (串口通信Verilog HDL代码)

UART Verilog HDL代码,经过RTL仿真和FPGA验证。 波特率支持9600~921600等8种,并支持灵活可配。

FPGA模块化设计实战:从架构蓝图到可复用IP核

本文详细介绍了FPGA模块化设计的实战经验,从架构规划到可复用IP核的实现。通过UART控制器IP核的设计案例,展示了模块化设计在可维护性、可复用性和可扩展性方面的优势,并提供了Verilog代码示例和参数化设计技巧,帮助开发者提升FPGA开发效率。

weixin_30824479的博客 432

uart的verilog代码

用verilog写的uart代码 适合初学者练练手 工程已经建好了

FIFO深度计算实战:跨时钟域与高速接口的资源-功能平衡

FIFO深度是数字系统中缓冲设计的核心参数,本质是解决写入与读出速率在时间维度上的瞬态失配问题。其原理源于数据流的突发性(burst)与读写时钟异步性,技术价值在于保障数据完整性、避免溢出/空读,并直接影响FPGA资源利用率与时序收敛。典型应用场景包括异步跨时钟域通信、FMC总线协议桥接、图像流水线行/帧缓存及UART/RS485收发切换。深度计算不能依赖标称带宽或静态公式,而需从真实硬件信号(如PCLK有效占比)、协议约束(如SPI CS空闲时间)和实测突发长度(T_burst)中提取关键参数。本文聚焦F

weixin_34216614的博客 208

5分钟快速搭建:使用ros1_bridge实现ROS2容器与ROS1主机的无缝通信

本文详细介绍了如何在5分钟内快速搭建基于ros1_bridge的通信方案,实现运行在Docker容器中的ROS2节点与宿主机ROS1系统的无缝数据交换。通过环境隔离、Docker容器化部署及选择性桥接配置,该方案能有效整合新旧系统,避免大规模代码重构,是机器人项目渐进式升级的实用策略。

weixin_29268637的博客 179

医疗AI新思路:为什么Graph Neural Network能改善气道分割的漏检问题?

本文探讨了Graph Neural Network(GNN)在医疗AI领域改善气道分割漏检问题的创新应用。通过分析3D UNet等传统方法的局限性,揭示了GNN在图结构建模中的独特优势,特别是在捕捉细小末梢支气管方面的突破性表现。文章详细介绍了UNet-GNN混合架构的设计原理、实验性能对比及优化方向,为CT影像分析提供了新思路。

weixin_30379531的博客 224

从零搭建工业级数据采集站

今天咱们要组的这套装备有点意思:AD7606负责采集16位模拟信号,RTL8211千兆网卡做高速传输,SD卡当本地仓库,再配上串口做调试通道。遇到大流量时,优先保证AD采样数据的传输,SD卡写入可以暂时降速。遇到写保护的问题,先检查卡座的物理开关,再查CMD55+ACMD41初始化流程是否正确。FPGA数据采集系统 ,RTL8211千兆以太网,SD卡存储,AD7606数模转换,串口通信软件程序。FPGA数据采集系统 ,RTL8211千兆以太网,SD卡存储,AD7606数模转换,串口通信软件程序。

CjQYqIyjLwCW的博客 84

台积电技术研发实力

台积电技术研发实力 台积电在半导体行业的地位毋庸置疑。他们究竟有多强大,大部分读者了解得可能非常片面。从最新公布的2019年财报里,看看台积电的真正实力。 一、台积电在市场上的地位 根据公司财报,台积公司在先进制程技术、特殊制程技术,以及先进封装技术的发展上持续领先全球集成电路制造服务领域,2019年的市场占有率为52%。台积公司总体营收以地区划分(主要依据客户营运总部所在地),来自北美市场的营收占台积公司总体营收的60%、日本与中国大陆以外的亚太市场占9%、中国大陆市场占20%、欧洲、中东及非洲市场占6

吴建明wujianming_110117 1901

fpga/nv_hsb_ip代码分析

全部为 SystemVerilog(.sv该目录内没有 README、TCL、XDC 等元数据文件。位于,被本 IP 包含使用。

eloudy的专栏 214

记录一次PowerJob使用达梦数据库的配置

记录一次PowerJob使用达梦数据库的配置

早晨阳光一般暖的博客 2160

正确使用 SGLang 和 vLLM 中为 Qwen3 开启工具调用能力的完整指南

本文介绍了在vLLM和SGLang框架中部署Qwen3大模型并启用工具调用功能的方法。主要内容包括:vLLM中需配置--tool-call-parser hermes和--enable-auto-tool-choice参数,SGLang中使用--tool-call-parser qwen25参数;提供了完整的部署命令示例和测试工具调用的curl请求模板;对比了两个框架的关键参数差异;总结了常见问题解决方案和性能优化建议。正确配置后,Qwen3能够充分发挥其外部工具调用能力,为AI应用开发提供支持。

Ven%的博客 4453

SystemVerilog使用状态机设计uart模块

UART的全称是通用异步收发器;UART 只需要两条信号线:RXD 和 TXD,其中 RXD 是 UART 的接收端,TXD 是 UART 的发送端,接收与发送是全双工形式。对于FPGA来说,RXD 是input,TXD 是output。

FPGA摆渡人的博客 1731

2026 拉勾网:JA4+指纹绕过 + sign逆向 + 动态城市参数,月采集10万+数据实战

2026年拉勾网反爬技术全面升级,采用JA4+ TLS指纹识别、动态sign签名等多维度防护体系。本文提供工业级爬虫解决方案,通过curl_cffi模拟浏览器指纹、逆向sign加密算法、动态生成城市参数三大核心技术,实现高效稳定的数据采集。系统采用分层架构设计,包含任务调度、签名生成、多线程引擎等模块,单月可获取10万+条招聘数据。重点解析了JA4+指纹识别原理、传统方法的局限性,以及通过HMAC-SHA256算法逆向sign参数的完整过程。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 2395

SystemVerilog 接口验证系统

/ 配置AXI写事务。// 检查读取的数据。// 运行UVM测试。// 主设备modport。// 从设备modport。// 任务:APB写操作。// 任务:APB读操作。

nskksms的博客 888

工业级稳定!C# 实现 Modbus RTU 多设备并发通信实战

摘要:本文提出一种基于C#的Modbus RTU多设备并发通信方案,解决工业自动化中单线程通信的串口抢占、数据阻塞等问题。采用任务队列+线程安全锁+异步调度的三层架构,实现16台及以上RTU设备的稳定并发读写。方案包含串口管理单例、Modbus通信核心和任务调度层,支持超时重试、异常捕获等工业级容错机制。通过NModbus库和.NET框架,提供可直接用于工业现场的代码实现,已在工控项目中长期验证,有效提升多设备通信效率和稳定性。

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

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

上一篇: 使用Verilog HDL语言实现4位超前进位加法器
下一篇: 你问我FIFO有多深?
bleauchat
博客等级 码龄9年 3925粉丝 239原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值