仅仅给出下面一个电路图,让你画出Q1,Q2以及Q3的波形,并描述电路功能

第一个触发器的输入是第二个以及第三个触发器的输出的反馈,是Q1与Q2的或非;实际上就是同步三分频电路

只要触发器复位有初值即可,一般触发器复位初值为0,这里也默认为0,那么输入值在复位时应该为1.

那么当正常运行(复位无效)时,q0的第一个值为复位值延迟一拍并持续一个时钟,之后q1、q2就简单了。

module test(input rst_n,input clk,output out2);wire in1;reg q0, q1, q2;always@(posedge clk or negedge rst_n) beginif(!rst_n) beginq0 <= 1'b0;q1 <= 1'b0;q2 <= 1'b0;endelse beginq0 <= in1;q1 <= q0;q2 <= q1;endendassign in1 = !q0 & !q1;assign out2 = q2;endmodule

上面的三分频电路,占空比为1/3 ,为了实现50%的占空比,需要在第二个触发器后面加上一个下降沿触发的触发器,将第二个触发器生成的三分频与延迟一拍输出的三分频相或即可,电路图如下:

module div3(clk,rst_n,dout);input clik,rst_n;output dout;reg q0,q1,q2;wire d1;//上升沿触发的三分频,占空比为1/3always @(posedge clk or negedge rst_n)beginif(~rst_n)beginq0 <= 1'd0;q1 <= 1'd0;endelsebegin//移位q0 <= d1;q1 <= q1;endendassign d1=~q0 & ~q1;//将上升沿触发的三分频延时半个周期always @(negedge clk or negedge rst_n)beginif(~rst_n)q2 <= 1'd0;elseq2 <= q1;endassign dout=q2 | q1;//相或得出1/2占空比
endmodule

对于奇数倍分频,以N=3为例:首先使用上升沿触发生成一个1/3占空比的时钟,再用下降沿触发生成一个1/3占空比的时钟(或者将前面的时钟采用下降沿触发的FF打一拍),两者相或就可以得到一个三分频且占空比为1/2的时钟;

由D触发器构成其他的触发器

//实现JK触发器
module jk_ff(clk,rst_n,j,k,q);input clk,rst_n;input j,k;output reg q;always @(posedge clk or negedge rst_n)beginif(~rst_n)q <= 1'd0;elseq <= d;endassign d=(j && ~q) | (~k && q);
endmodule//实现T触发器
module t_ff(clk,rst_n,t,q);input clk,rst_n;input t;output reg q;always @(posedge clk or negedge rst_n)beginif(~rst_n)q <= 1'd0;elseq <= d;endassign d=t^q;
endmodule//实现T‘触发器
module t1_ff(clk,rst_n,q);input clk,rst_n;output reg q;always @(posedge clk or negedge rst_n)beginif(~rst_n)q <= 1'd0;elseq <= d;endassign d=~q;
endmodule

常见的分频电路原理图:

实质上就是一个4位的计数器,由Q0输出为二分频,由Q1输出为4分频,由Q2输出为8分频,由Q3输出为16分频;

一般的FPGA中触发器主要是D触发器,D触发器与T触发器之间的转换关系如下:

所以用D触发器来构成上面的计数器,电路图如下:

//计数器其实就是分频器
module div_2(clk,rst_n,q0,q1,q2,q3);input clk,rst_n;output reg q0,q1,q2,q3;wire d0,d1,d2,d3;always @(posedge clk or negedge rst_n)beginif(~rst_n){q3,q2,q1,q0} <= 4'd0;else{q3,q2,q1,q0} <= {d3,d2,d1,d0};endassign d0=1'd1^q0;assign d1=q1^q0;assign d2=(q1&q0)^q2;assign d3=(q2&q1&q0)^q3;//q0输出为2分频,q1输出为4分频,q2输出为8分频,q3输出为16分频,且占空比都是50%//{q3,q2,q1,q0}为模16计数器
endmodule

任意分频,实现任意占空比 

module div(clk,rst_n,clk_o);input clk,rst_n;output reg clk_o;parameter M,N;reg [3:0] count;always @(posedge clk or negedge rst_n)beginif(~rst_n)beginclk_o <= 1;count <= 0;endelse if(count == M)//占空比为M+1/Nbegincount <= count + 1'd1;clk_o <= ~clk_o;endelse if(count == N-1)begincount <= 4'd0;clk_o <= ~clk_o;endelsecount <= count + 1'd1; end
endmodule

下面是异步4位计数器,不推荐使用:

这种设计每个触发器都有一定的延时,会出问题的!!慎用

什么是Clock Jitter和Clock Skew,这两者有什么区别?

时钟抖动(Clock Jitter):指芯片的某一个给定点上时钟周期发生暂时性变化,使得时钟周期在不同的周期上可能加长或缩短。

时钟偏移(Clock Skew):是由于布线长度及负载不同引起的,导致同一个时钟信号到达相邻两个时序单元的时间不一致。

区别:Jitter是在时钟发生器内部产生的,和晶振或者PLL内部电路有关,布线对其没有影响Skew是由不同布线长度导致的不同路径的时钟上升沿到来的延时不同

什么是冒险和竞争,如何消除?

下面这个电路,使用了两个逻辑门,一个非门和一个与门,本来在理想情况下F的输出应该是一直稳定的0输出,但是实际上每个门电路从输入到输出是一定会有时间延迟的,这个时间通常叫做电路的开关延迟。而且制作工艺、门的种类甚至制造时微小的工艺偏差,都会引起这个开关延迟时间的变化

实际上如果算上逻辑门的延迟的话,那么F最后就会产生毛刺。信号由于经由不同路径传输达到某一汇合点的时间有先有后的现象,就称之为竞争,由于竞争现象所引起的电路输出发生瞬间错误的现象,就称之为冒险,FPGA设计中最简单的避免方法是尽量使用时序逻辑同步输入输出;

  1. 加滤波电容,消除毛刺的影响

  2. 加选通信号,避开毛刺

  3. 增加冗余项,消除逻辑冒险

用verilog实现两路数据的乘法运算,要求只使用1个乘法器;

input clk ;
input rst_n ;
input sel_x ;
input [ 7:0] da_x ;
input [ 7:0] da_y ;
input [ 7:0] db_x ;
input [ 7:0] db_y ;
output reg [15:0] dout_x_y ; 
module test(input              clk,input              rst_n,input              sel_x,input       [ 7:0] da_x, input       [ 7:0] da_y, input       [ 7:0] db_x, input       [ 7:0] db_y, output  reg [15:0] dout_x_y);wire    [ 7:0] da;wire    [ 7:0] db;wire    [15:0] dout;
assign da = sel_x ? da_x : da_y;
assign db = sel_x ? db_y : db_x;
assign dout = da * db ;always @(posedge clk or negedge rst_n) beginif (!rst_n) begindout_x_y <= 16'd0;end else begindout_x_y <= dout;end
end
endmodule

用verilog实现串并转换

1) lsb优先 2) msb优先

input clk;rst_n, data_i;output [7:0] data_o;
module test(input clk, rst_n, data_i,output [7:0] data_o);reg [7:0] data_r;reg [2:0] cnt;
//lsb
always @(posedge clk or negedge rst_n) beginif (!rst_n) begindata_r <= 8'd0;cnt <= 3'b0;end else begindata_r <= {data_r[6:0],data_i};cnt <= cnt + 1'b1;end
end
//msb
/* always @(posedge clk or negedge rst_n) beginif (!rst_n) begindata_r <= 8'd0;cnt <= 3'b0;end else begindata_r <= {data_i,data_r[7:1]};cnt <= cnt + 1'b1;end
end */assign data_o = (cnt == 3'd7) ? data_r : data_o;
endmodule

 用verilog实现乘法y = a * b ,a和b都是8bit,考虑三种情况:

1) 都是无符号数

2) 都是有符号数

3) a是有符号数,b是无符号数

1)module test19(input       [ 7:0]  i_a     ,input       [ 7:0]  i_b     ,output      [15:0]  o_y);
assign o_y = i_a * i_b;
endmodule
2)module test19(input    signed   [ 7:0]  i_a     ,input    signed   [ 7:0]  i_b     ,output   signed   [14:0]  o_y);assign o_y = i_a * i_b;//7+7+1
endmodule
3)module test19(input    signed   [ 7:0]  i_a     ,//加上signed后,将数看做二进制补码input             [ 7:0]  i_b     ,//无符号数,也就是正数output   signed   [15:0]  o_y);wire    signed  [8:0]   b_r;assign b_r = {1'b0,i_b};//加0不会出错,因为正数的补码与原码相同assign o_y = i_a * b_r;//7+8+1
endmodule

用Verilog实现 z = abs(x - y)

1) x和y是8bit无符号数

2) x和y是8bit有符号数(2补码)

1)module abs(input   [7:0]   i_x,input   [7:0]   i_y,output [7:0]   o_z);assign  o_z= (i_x > i_y) ? (i_x - i_y) : (i_y - i_x);endmodule
2)考虑溢出问题,结果应该为9bit:
module abs(input  signed [7:0]   i_x,input  signed [7:0]   i_y,output        [8:0]   o_z);wire   signed [8:0]   z_r;
assign  z_r = (i_x > i_y) ? (i_x - i_y) : (i_y - i_x);assign  o_z = z_r;endmodule

用Verilog实现 y(n) = 0.75x(n) + 0.25y(n-1),x和y是8bit无符号数

module Cal_Formula(input           clk,input           rst_n,input   [7:0]   din,output reg [7:0]   dout);// y(n) = 0.75x(n) + 0.25y(n-1) //0.75*4 = 3,0.25*4 = 1reg     [7:0]   dout_r1=0;reg     [9:0]   dout_r2;always @(posedge clk or negedge rst_n)beginif(!rst_n)dout_r1 <= 0;else dout_r1 <= dout;//将输出作为下一个输入endalways @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)begindout_r2 <= 0;endelse begindout_r2 <= 3 * din + dout_r1;endendassign  dout = dout_r2 >> 2; //除4endmodule

画出SRAM bit cell结构图

SRAM存储的原理就是基于双稳态电路,将两个反相器的输入与输出分别交叉连接,然后再利用两个MOS管作为字线进行选通,总共需要6个MOS管

D锁存器和D触发器的原理图

状态机练习,序列检测

//检测1101
module detect1101(clk,rst_n,din,mealy_out,moore_out);input clk,rst_n;input din;output reg mealy_out,moore_out;parameter s0=3'b000,s1=3'b001,s2=3'b010,s3=3'b011,s4=3'b100;//时序逻辑描述状态转移reg [2:0] cs,ns;always @(posedge clk or negedge rst_n)beginif(~rst_n)begincs <= s0;endelsebegincs <= ns;endend//组合逻辑描述下一个状态always @(*)beginif(~rst_n)beginns = s0;endelsebeginns = s0;//默认状态case(cs)s0: ns = (din == 1'b1)? s1:s0;s1: ns = (din == 1'b1)? s2:s0;s2: ns = (din == 1'b1)? s2:s3;s3: ns = (din == 1'b1)? s4:s0;s4: ns = (din == 1'b1)? s1:s0;endcaseendend//打一拍作为输出always @(posedge clk or negedge rst_n)beginif(~rst_n)beginmoore_out <= 1'd0;mealy_out <= 1'd0;endelsebeginmoore_out <= (cs == s4)? 1'd1:1'd0;//moore机的输出只与当前状态有关mealy_out <= (cs == s3 && din == 1'd1)?1'd1:1'd0;//mealy机的输出与当前状态和输入有关//moore机总是比mealy机慢一拍输出endend
endmodule

在clk a时钟域的一个单周期脉冲信号,如何正确的传递到clk b时钟域? 要考虑clk a和b的各种不同频率/相位的场景

//慢时钟域到快时钟域,两级寄存器同步,也就是打两拍reg signal_in;reg     [1:0]   signal_r;always @(posedge clk_a or negedge rst_n)beginif(rst_n == 1'b0)beginsignal_in <= 0;endelse beginsignal_in <= datain;endend//-------------------------------------------------------always @(posedge clk_b or negedge rst_n)beginif(rst_n == 1'b0)beginsignal_r <= 2'b00;endelse beginsignal_r <= {signal_r[0], signal_in};endendassign  signal_out = signal_r[1];
//快时钟域到慢时钟域//Synchronousmodule Sync_Pulse(input           clka,input           clkb,input           rst_n,input           pulse_ina,output          pulse_outb,output          signal_outb);//-------------------------------------------------------reg             signal_a;reg             signal_b;reg     [1:0]   signal_b_r;reg     [1:0]   signal_a_r;//-------------------------------------------------------//在clka下,生成展宽信号signal_aalways @(posedge clka or negedge rst_n)beginif(rst_n == 1'b0)beginsignal_a <= 1'b0;endelse if(pulse_ina == 1'b1)beginsignal_a <= 1'b1;endelse if(signal_a_r[1] == 1'b1)signal_a <= 1'b0;else signal_a <= signal_a;//将信号pulse_ina展宽end//-------------------------------------------------------//在clkb下同步signal_aalways @(posedge clkb or negedge rst_n)beginif(rst_n == 1'b0)beginsignal_b <= 1'b0;endelse beginsignal_b <= signal_a;//0 0 0 ... 1 1 1 endend//-------------------------------------------------------//在clkb下生成脉冲信号和输出信号always @(posedge clkb or negedge rst_n)beginif(rst_n == 1'b0)beginsignal_b_r <= 2'b00;endelse beginsignal_b_r <= {signal_b_r[0], signal_b};endendassign    pulse_outb = ~signal_b_r[1] & signal_b_r[0];assign    signal_outb = signal_b_r[1];//0 0 0 1......//-------------------------------------------------------//在clka下采集signal_b[1],生成signal_a_r[1]用于反馈拉低signal_aalways @(posedge clka or negedge rst_n)beginif(rst_n == 1'b0)beginsignal_a_r <= 2'b00;endelse beginsignal_a_r <= {signal_a_r[0], signal_b_r[1]};//反馈,防止脉冲继续展宽endendendmodule

要将一个信号从快时钟域传递到慢时钟域,首先要在快时钟域展宽脉冲,然后将展宽的脉冲传递到慢时钟域,如果在慢时钟域检测到脉冲后就可以给快时钟域一个反馈以阻止脉冲的继续展宽;

 用verilog实现1bit信号边沿检测功能,输出一个周期宽度的脉冲信号

要实现边缘检测,采样时钟的频率必须在信号频率的两倍以上,否则就很可能出现漏采样,代码如下:

module edge_detect(clk,rst,signal,pos_edge,neg_edge,both_edge);input clk;input rst;input signal;output pos_edge;output neg_edge;output both_edge;reg sig_r0,sig_r1;//状态寄存器always @(posedge clk)beginif(rst)beginsig_r0 <= 1'b0;sig_r1 <= 1'b0;endelsebeginsig_r0 <= signal;sig_r1 <= sig_r0;endendassign pos_edge = ~sig_r1 & sig_r0;//上升沿assign neg_edge = sig_r1 & ~sig_r0;//下降沿assign both_edge = sig_r0 ^ sig_r1;//双边沿检测
endmodule

用Verilog实现取整函数(ceil、floor、round)。以5bit为例,小数部分1位,取整后保留4bit 

wire [4:0] data;

wire [3:0] data_ceil;

wire [3:0] data_floor;

wire [3:0] data_round;

基础知识:

floor(x),表示不超过x的整数中最大的一个,朝负无穷方向取整;

ceil(x),表示不小于x的整数中最小的一个,朝正无穷方向取整;

round(x)四舍五入到最近的整数

思路:data为有符号数(2补码),只有1bit的小数位,精度有限,所以假设data都是小数,例如整数部分是7,则data只能表示大于7.5或小于7.5的小数,不表示整数7;

floor——非负取整即可,负数取整减一;

ceil——正数,取整+1,非正数取整即可;

round——小数位为1,取整+1;小数位为0,取整即可 ;

module quzheng(input   [4:0] data      ,output  [3:0] data_ceil ,output  [3:0] data_floor,output  [3:0] data_round);assign data_ceil = (data[4] == 1'b0) ? {1'b0,data[3:1]+1'b1} : data[4:1];//先判断符号位,向正无穷取整assign data_floor = (data[4] == 1'b0) ? data[4:1] : data[4:1]-1'b1;//先判断符号位,向负无穷取整assign data_round = (data[0] == 1'b0) ? data[4:1] : data[4:1]+1'b1;
endmodule

异步fifo的设计

异步fifo主要分为:双端口RAM、空满标志位判断逻辑、跨时钟域指针传输模块

(1)双端口RAM用于接收空满判断逻辑模块传送过来的读写地址进行读写操作;

(2)空满标志位判断逻辑用于判断full、empty,同时输出读写地址指针以及对应的格雷码;

(3)跨时钟域传输主要是对地址指针进行打两拍操作,将读地址指针传输到写时钟域用于判断full,将写地址指针传输到读时钟域用于判断empty;

module sync_r2w //将读地址传输到写时钟域
#(parameter ADDRSIZE = 4)
(output reg [ADDRSIZE:0] wq2_rptr,input      [ADDRSIZE:0] rptr,//输入的读地址为格雷码input                       wclk, wrst_n
);
reg [ADDRSIZE:0] wq1_rptr;
always @(posedge wclk or negedge wrst_n)if (!wrst_n) {wq2_rptr,wq1_rptr} <= 0;else {wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr};
endmodule
module rptr_empty //在读时钟域判断是否empty
#(parameter ADDRSIZE = 4)
(output reg rempty,output     [ADDRSIZE-1:0] raddr,output reg [ADDRSIZE :0]  rptr,input       [ADDRSIZE :0] rq2_wptr,//输入的写地址为格雷码input       rinc, rclk, rrst_n);//rinc为读使能reg  [ADDRSIZE:0] rbin;
wire [ADDRSIZE:0] rgraynext, rbinnext;
wire  rempty_val;
//-------------------
// GRAYSTYLE2 pointer: gray码读地址指针
//-------------------
always @(posedge rclk or negedge rrst_n)if (!rrst_n) begin rbin <= 0;rptr <= 0;endelsebeginrbin <= rbinnext ; rptr <= rgraynext;//下一个读地址的格雷码end
// gray码计数逻辑
assign rbinnext = !rempty ? (rbin + rinc) : rbin;//若不为空,则读地址加1作为下一个读地址
assign rgraynext = (rbinnext>>1) ^ rbinnext;      //二进制到gray码的转换,将右移一位的结果与原来的数异或assign raddr = rbin[ADDRSIZE-1:0];//下一个读地址作为输出
//---------------------------------------------------------------
// FIFO empty when the next rptr == synchronized wptr or on reset
//---------------------------------------------------------------
/*
*   读指针是一个n位的gray码计数器,比FIFO寻址所需的位宽大一位
*   当读指针和同步过来的写指针完全相等时(包括MSB),说明二者折回次数一致,FIFO为空
*
*/
assign rempty_val = (rgraynext == rq2_wptr);//比较读写指针的格雷码always @(posedge rclk or negedge rrst_n)
if (!rrst_n) rempty <= 1'b1;//若复位,则空信号置1
else rempty <= rempty_val;
endmodule

这里要注意,对于读写指针的位宽通过会比fifo深度所需位宽多出一位,用于判断是否满;如果两个地址指针完全相同,包括最高位也相同,那么empty;如果两个指针除了最高位都相同,则full;

同步fifo的设计

module fifo(clk,rst,w_en,r_en,data_in,data_out,empty,full);input clk,rst;input w_en,r_en;input [7:0] datain;output reg [7:0] data_out;output empty,full;reg [7:0] ram [15:0];//双端口RAMreg [3:0] w_pt,r_pt;reg [3:0] count;always @(posedge clk or negedge rst_n)beginif(~rst_n)beginw_pt <= 'd0;r_pt <= 'd0;count <= 'd0;count <= 'd0;endelsebegincase({w_en,r_en})2'b00: count <= count;2'b01:begin//读data_out <= ram[r_pt];count <= count - 1'd1;r_pt=(r_pt== 4'd15)?0:r_pt+1'd1;end2'b10:begin//写ram[r_pt] <= data_in;count <= count + 1'd1;w_pt=(w_pt== 4'd15)?0:w_pt+1'd1;end2'b11:begin//写读ram[r_pt] <= data_in;//count <= count + 1'd1;w_pt=(w_pt== 4'd15)?0:w_pt+1'd1;data_out <= ram[r_pt];//count <= count - 1'd1;r_pt=(r_pt== 4'd15)?0:r_pt+1'd1;endendcaseendendassign full=(count == 4'd15)? 1:0;assign empty=(count == 4'd0)? 1:0;
endmodule

用16bit加法器IP核实现8bit乘法运算

乘法器最通用的实现方式就是使用移位相加来实现,如下:

module mul8bits(input clk,input rst_n,input [7:0] a,input [7:0] b,output reg [15:0] result);reg [15:0] areg;reg [15:0] temp;reg [3:0] cnt;always@(posedge clk or negedge rst_n)beginif(~rst_n) beginareg <= {8{1'b0}, a};temp <= 16'd0;//用来保存移位相加的结果cnt <= 4'd0;result <= 16'd0;endelse if(cnt <= 7) beginif(b[cnt]) begin//判断b的8个bit是否为1,如果为1则加上相应的移位结果temp <= temp + areg;else //如果为0则加0temp <= temp;endcnt <= cnt + 1;areg <= areg <<1;endelse begincnt <= cnt;areg <= {8{1'b0},a};result <= temp;endend
endmodule

将上面移位相加的操作采用16bit的加法器来实现,如下:

module mul8bits(input clk,input rst_n,input [7:0] a,input [7:0] b,output reg [15:0] result);reg [15:0] areg;reg [15:0] temp;reg [3:0] cnt;always@(posedge clk or negedge rst_n)beginif(~rst_n) beginareg <= {8{1'b0}, a};temp <= 16'd0;cnt <= 4'd0;result <= 16'd0;endelse if(cnt <= 7) begincnt <= cnt + 1;areg <= areg <<1;if(b[cnt]) temp <= temp_w; //调用IP核else temp <= temp;endelse begincnt <= cnt;areg <= {8{1'b0},a};result <= temp;endendwire [15:0] temp_w;add16 inst_add16(.in1(temp),.in2(areg),.sout(temp_w),.cout(1'd0));
endmodule

在Verilog中设计模块以满足以下要求:
(1)频率为100MHz的时钟
(2)对时钟敏感的4位宽信号,限制该信号在8到15的范围内随机化16次

`timescale 1ns/1ps
module random1();
reg clk;
reg [3:0] out_rand;initial beginclk  = 0;forever #5 clk = ~clk;
endinteger i;initial beginfor(i = 0;i < 16; i = i + 1) begin@(posedge clk) beginout_rand = 4'b1000+ {$random}%8;endend
end
endmodule

反相器的速度与哪些因素有关?什么是转换时间(Transition Time)和传播延迟(Propagation Delay)?

反相器的速度与哪些因素有关: 1. 电容(负载电容、自载电容、连线电容)较小,漏端扩散区的面积应尽可能小。输入电容要考虑: (1)Cgs 随栅压而变化(2)密勒效应(3)自举效应 2. 加大晶体管的尺寸(驱动能力),使晶体管的等效导通电阻(输出电阻)较小。但这同时加大自载电容和负载电容(下一级晶体管的输入电容)。 3. 提高电源电压,提高电源电压可以降低延时,即用功耗换取性能但超过一定程度后改善有限。电压过高会引起可靠性问题(氧化层击穿、热电子等)。

Transition Time(转换时间):上升时间:从10%Vdd上升到90%Vdd的时间,下降时间L从90%Vdd下降到10%dd的时间。上升时间和下降时间统称为Transition Time,也有定义为20%到80%。 Propagation Delay(传播延时):在输入信号变化到50%Vdd到输出信号变化到50%Vdd之间的时间

相同面积的cmos与非门和或非门哪个更快?

电子迁移率是空穴的2.5倍(在硅基CMOS工艺中),运算就是用这些大大小小的MOS管驱动后一级的负载电容,翻转速度和负载大小一级前级驱动能力相关。为了上升延迟和下降延迟相同,PMOS需要做成NMOS两倍多大小

载流子的迁移率,对PMOS而言,载流子是空穴;对NMOS而言,载流子是电子;

PMOS采用空穴导电,NMOS采用电子导电,由于PMOS的载流子的迁移率比NMOS的迁移率小,所以,同样尺寸条件下,PMOS的充电时间要大于NMOS的充电时间长,在互补CMOS电路中,与非门是PMOS管并联,NMOS管串联,而或非门正好相反,所以,同样尺寸条件下,与非门的速度快,所以,在互补CMOS电路中,优先选择与非门

FPGA与ASIC设计流程的区别

首先我们要清楚FPGA的基本单元是LUT,而ASIC的基本单元是寄存器;

对于FPGA:首先要进行模块划分,然后编写RTL代码,进行RTL仿真,综合后将生成的网表文件在FPGA上实现,也就是布局布线,该步骤完成后进行STA,没有问题的话就生成bit流文件,将bit流文件烧录到FPGA开发板上进行板级调试;

对于ASIC:模块划分、RTL设计、验证、综合、STA、形式验证、布局规划、DRC设计规则检查、时钟树综合、生成GDSII文件;

C语言实现冒泡排序

#include <stdio.h>//头文件
int main(void)
{int a[] = {900, 2, 3, -58, 34, 76, 32, 43, 56, -70, 35, -234, 532, 543, 2500};int n;  //存放数组a中元素的个数int i;  //比较的轮数int j;  //每轮比较的次数int buf;  //交换数据时用于存放中间数据n = sizeof(a) / sizeof(a[0]);  /*a[0]是int型, 占4字节, 所以总的字节数除以4等于元素的个数*/for(i=0;i<n-1;i++)//比较n-1轮{for(j=0;j<n-i-1;j++){if(a[j]>a[j+1]){buf=a[j];a[j]=a[j+1];a[j+1]=buf;}}}for(i=0;i<n;i++){printf("%d\n",a[i]);}return 0;//注意加上
}

已知一个数据的数值范围为1~43,运算并输出其除3的余数;

input [5:0] a;//被除数
input [5:0] b;//除数
output reg [5:0] y_shang;
output reg [5:0] y_yu;//商和余数
reg [11:0] tempa;
reg [11:0] tempb;integer i;
always @(*)begintempa={6'd0,a};tempb={b,6'd0};for(i=0;i<6;i++)begintempa=tempa << 1;//每次左移1位tempa=(tempa[11:6]>=tempb[11:6])?(tempa - tempb + 1'b1):tempa;endy_yu=tempa[11:6];y_shang=tempa[5:0];end//改用时序逻辑,分为13个周期
always @(posedge clk or negedge rst_n)beginif(~rst_n)beginy_shang <= 'd0;y_yu <= 'd0;endelse if(enable)beginy_yu <=tempa[11:6];y_shang <=tempa[5:0];endelsebeginy_shang <= 'd0;y_yu <= 'd0;endend reg [3:0] count;
always @(posedge clk or negedge rst_n)beginif(~rst_n)count <= 'd0;else if(count == 4'd12)count <= 'd0;else count <= count + 1'd1;
endalways @(posedge clk or negedge rst_n)beginif(~rst_n)begintempa <= 'd0;tempb <= 'd0;endelse if(count == 'd0)begintempa <= {6'd0,a};tempb <= {b,6'd0}endelse if(count[0] == 1'b1)tempa <= tempa << 1;elsetempa <= (tempa[11:6] >= tempb[11:6])? (tempa - tempb + 1'b1):tempa;end reg enable;always @(posedge clk or negedge rst_n)beginif(~rst_n)enable <= 1'd0;//else if(count == 0)//  enable <= 1'd0;else if(count == 4'd12)enable <= 1'd1;elseenable <= 1'd0;end

二进制序列检测的移位寄存器实现

以前看到二进制序列检测一般都使用状态机实现,今天突然想到可以使用移位寄存器实现,移位寄存器就好像一个窗口,把从窗口里截取的数据接到一个比较器上,这样比较不同序列时只要换一下比较器另一个输入端的数据就可以实现,需要改变的只是寄存器和比较器的位宽;

module seq_det(iBit,CLK,RSTn,iKEY,Q);
input   iBit;
input[4:0]  iKEY;
input   CLK;
input   RSTn;
output   Q;reg[4:0]  shift_reg;always@(posedge CLK or negedge RSTn)
beginif(RSTn==0)shift_reg <= 0;elseshift_reg <= {shift_reg[3:0],iBit};
endassign Q =(shift_reg==iKEY)?1:0;
endmodule

定义一个随机数,并约束其范围为4~100,并建仓

rand bit [6:0] a;constraint value_a{a>4;a<100;}covergroup ag @(posedge clk)coverpoint : a {bins a1[]={[4:100]};}
endgroup

将两个乘法器减少为1个,同时数据选择器多用了1个;

fir滤波器的设计

module fir(clk,rst,din,dout,ordy);input clk;input rst;input [7:0] din;output [15:0] dout;output ordy;//matlab fir生成系数 * 256  该滤波器采样率为100Hz,截止频率为10Hzparameter coeff1=8'd5,coeff2=8'd17,coeff3=8'd43,coeff4=8'd63,coeff5=8'd63,coeff6=8'd43,coeff7=8'd17,coeff8=8'd5;//8个寄存器reg  signed [7:0]  sample_1;reg  signed [7:0]  sample_2;reg  signed [7:0]  sample_3;reg  signed [7:0]  sample_4;reg  signed [7:0]  sample_5;reg  signed [7:0]  sample_6;reg  signed [7:0]  sample_7;reg  signed [7:0]  sample_8;reg [18:0] dout;reg ordy;//输入数据,移位寄存always @(posedge clk )beginif(rst)beginsample_1 <= 8'd0;sample_2 <= 8'd0;sample_3 <= 8'd0;sample_4 <= 8'd0;sample_5 <= 8'd0;sample_6 <= 8'd0;sample_7 <= 8'd0;sample_8 <= 8'd0;endelsebeginsample_1 <= din;sample_2 <= sample_1;sample_3 <= sample_2;sample_4 <= sample_3;sample_5 <= sample_4;sample_6 <= sample_5;sample_7 <= sample_6;sample_8 <= sample_7;//8个周期完成移位,完成滞后endend//调用ip,执行乘法wire [15:0] p[8:1];mult_8 u1 (.CLK(clk),  // input wire CLK.A(sample_1),      // input wire [7 : 0] A.B(coeff1),      // input wire [7 : 0] B.P(p[1])      // output wire [15 : 0] P 设置pipline stage 为3,表示3级延时
);mult_8 u2 (.CLK(clk),  // input wire CLK.A(sample_2),      // input wire [7 : 0] A.B(coeff2),      // input wire [7 : 0] B.P(p[2])      // output wire [15 : 0] P
);mult_8 u3 (.CLK(clk),  // input wire CLK.A(sample_3),      // input wire [7 : 0] A.B(coeff3),      // input wire [7 : 0] B.P(p[3])      // output wire [15 : 0] P
);mult_8 u4 (.CLK(clk),  // input wire CLK.A(sample_4),      // input wire [7 : 0] A.B(coeff1),      // input wire [7 : 0] B.P(p[4])      // output wire [15 : 0] P
);mult_8 u5 (.CLK(clk),  // input wire CLK.A(sample_5),      // input wire [7 : 0] A.B(coeff5),      // input wire [7 : 0] B.P(p[5])      // output wire [15 : 0] P
);mult_8 u6 (.CLK(clk),  // input wire CLK.A(sample_6),      // input wire [7 : 0] A.B(coeff6),      // input wire [7 : 0] B.P(p[6])      // output wire [15 : 0] P
);mult_8 u7 (.CLK(clk),  // input wire CLK.A(sample_7),      // input wire [7 : 0] A.B(coeff7),      // input wire [7 : 0] B.P(p[7])      // output wire [15 : 0] P
);mult_8 u8 (.CLK(clk),  // input wire CLK.A(sample_8),      // input wire [7 : 0] A.B(coeff8),      // input wire [7 : 0] B.P(p[8])      // output wire [15 : 0] P
);//加法第一级wire [16:0] s1 [4:1];//加法器的延时为2add_16 a1 (.A(p[1]),      // input wire [15 : 0] A.B(p[2]),      // input wire [15 : 0] B.CLK(clk),  // input wire CLK.S(s1[1])      // output wire [16 : 0] S
);add_16 a2 (.A(p[3]),      // input wire [15 : 0] A.B(p[4]),      // input wire [15 : 0] B.CLK(clk),  // input wire CLK.S(s1[2])      // output wire [16 : 0] S
);add_16 a3 (.A(p[5]),      // input wire [15 : 0] A.B(p[6]),      // input wire [15 : 0] B.CLK(clk),  // input wire CLK.S(s1[3])      // output wire [16 : 0] S
);add_16 a4 (.A(p[7]),      // input wire [15 : 0] A.B(p[8]),      // input wire [15 : 0] B.CLK(clk),  // input wire CLK.S(s1[4])      // output wire [16 : 0] S
);//加法第二级wire [17:0] s2 [2:1];add_17 a21 (.A(s1[1]),      // input wire [16 : 0] A.B(s1[2]),      // input wire [16 : 0] B.CLK(clk),  // input wire CLK.S(s2[1])      // output wire [17 : 0] S
);add_17 a22 (.A(s1[3]),      // input wire [16 : 0] A.B(s1[4]),      // input wire [16 : 0] B.CLK(clk),  // input wire CLK.S(s2[2])      // output wire [17 : 0] S
);//加法第三级wire [18:0] s3;add_18 a31 (.A(s2[1]),      // input wire [17 : 0] A.B(s2[2]),      // input wire [17 : 0] B.CLK(clk),  // input wire CLK.S(s3)      // output wire [18 : 0] S
);//计数reg [4:0] counter;always @(posedge clk)beginif(rst)begincounter <= 5'd0;dout <= 19'd0;ordy <= 1'b0;endelse if(counter == 17)begindout <= s3;ordy <= 1'b1;endelsebegindout <= 19'd0;counter <= counter + 1'b1;endend
endmodule

#include <stdio.h>int main()
{char *str=(char *)malloc(100);strcpy(str,"hello");printf("%s\n",str);free(str);//释放了str所指向地址中的内容,并没有释放指针printf("%d\n",&str);printf("%s\n",str);if(str != NULL){strcpy(str,"world");printf("%s\n",str);}
}

在测试文件里,always是一个循环,就像我们写生成时钟一样,有种写法就是:

initial clk = 0;always begin
#2 clk = ~clk;end

那这里的always同样也是循环语句的作用,内部是阻塞赋值,@(A)以及@(B)相当于触发条件,#2其实也属于这一类,过了2ns执行下面的语句,这里就是A变化了就触发,题目中说A在15ns以及25ns各触发一次,当A在15ns触发一次后,count = 2,然后等待@(B),可是B一直为X态,没有触发,所以就一直阻塞到这里了,再多的时间也没用。所以只能最后count = 2.

设计一个可预置初值的7进制循环计数器

module counter7(clk,rst,load,data,cout);input clk,rst,load;input [2:0] data;output reg [2:0] cout;always@(posedge clk)beginif(!rst)cout<=3’d0;else if(load)cout<=data;      else if(cout>=3’d6)cout<=3’d0;elsecout<=cout+3’d1;//不同位宽的数相加会自动补齐end
endmodule

用verilog实现冒泡排序

module sort(clk,rst,datain,dataout,over);parameter length=8;           // the bits number of data
parameter weikuan=256;         // the length of the memoryinput clk,rst;
input[length-1:0] datain;
output[length-1:0] dataout;
output over;reg over;
reg [length-1:0] dataout;
reg [length-1:0] memo[weikuan-1:0];integer i,j,m;//**************数据交换任务模块************//
task exchange;inout[length-1:0] x,y;  reg[length-1:0] temp;beginif(x<y)begintemp=x;x=y;y=temp;endend
endtask
//***********************************************always@(negedge clk or posedge rst)
if(!rst)begini=0;j=0;m=0;over=0;end
elseif(m==weikuan-1)  //the memory is fullbeginm=weikuan-1;if(i==weikuan) //arrangement is over, set over to be  "1"begini=weikuan;over=1;endif(i<weikuan)for(i=0;i<weikuan;i=i+1)        //then  put the datas in orderbeginfor(j=0;j<weikuan-1-i;j=j+1) //note the range of 'j'exchange(memo[j+1],memo[j]); //if 'memo[j+1]<memo[j]', exchange them.endendelse            //input the data firstbeginmemo[m]=datain;  m=m+1;end                                    endmodule

数字倍频电路

奉上代码:


module clk_mul(input   wire            clk
,   input   wire            rst_n
,   output  wire            clk_out
);
//
// variable declaration
reg     temp_mul    ;
//
// logic
always @(posedge clk_out or negedge rst_n) beginif(~rst_n)                      temp_mul    <=  1'b0            ;else                            temp_mul    <=  #2 ~temp_mul    ;
end
assign  clk_out =   ~(clk ^ ~temp_mul)  ;endmodule   //          CREATED by poiu_elab@1207

这个东西很简单的,但是要注意,它的核心是第16行的#2,这里的延时(占空比)可以通过电路的Tco和经过反相器的时间来搞定(其中可以插入一些buffer来调节时间),testbench这么来写(很简单,但是便于下面解释延时对占空比的影响还是附上):

`define CLK_CYCLE   20
module tb();
///
// variable declaration
reg             clk         ;
reg             rst_n       ;
wire            clk_out     ;
///
// stimulation generation
initial forever #(`CLK_CYCLE/2) clk = ~clk;
initial beginrst_n           =   1'b0            ;clk             =   1'b1            ;
#500;rst_n           =   1'b1            ;
#5000;
$stop;
end
///
// module instaniation
clk_mul u_clk_mul(.clk        (   clk     )
,   .rst_n      (   rst_n   )
,   .clk_out    (   clk_out )
);
///endmodule   

下面给出仿真图,当#2的时候,是这样的,其中你要关心的其实是~temp_mul & clk, 当你要是q端经过反相器的信号与接入的clk信号相同的时候你的clk_out就会起来,之后你的q端翻转了的话,你的clk_out就会落下来,这时候在下一个clk翻转的时候,你的~temp_mul & clk就会又要把clk_out拉起来,q端又翻转,以此类推,就可以继续在每个clk的跳变沿出现你的clk_out的高电平,调整你的Tco和反相器延时就可以调整你的高电平时间,由于周期又是固定的,这样就可以调整你的占空比;

而当#5的时候,是这样的

看出什么端倪了没,当你的延时,正好是时钟周期的1/4的时候,你就可以得到一个占空比是50%的2倍频时钟;

要求:一个握手的模块。输入信号分别为en,ack,all_done;输出信号是req,done;要求例如以下en高电平有效时能够输出req信号。然后等待ack信号,收到ack信号后会发出done信号,模块的数量不定。当全部模块done信号军发送完成后会接收到all_done信号,仅仅有接收到aLL_done信号才干够发送下一次req信号

module handshake(input clk, rst_n,en,all_done,ack,output reg req, done);reg flag,r_all;always @(posedge clk or negedge rest_n)if(!rst_n)beginflag<=1'b1;//推断是否为第一次发送,flag为标志位r_all<=1'b0; //是否接收到all_done信号endelse if(all_done) beginr_all<=1'b1;//已接收到all_done信号置位endelse if(done) beginr_all<=1'b0;//以完毕发送,all_done信号清零flag<=1'b0;//完毕第一次发送后即永久性清零。endalways @(posedge clk or negedge rest_n)if(!rst_n)beginreq<=1'b0;done<=1'b0;endelse beginif((en&flag) || (en&all_done) || (en &r_all)) req<=1'b1;else  req<=1'b0;if(ack)done<=1'b1;else  done<=1'b0;endendmodule

一个1bit的信号,脉冲宽度为一个源时钟周期,需要传送到到频率低得多的目的时钟域,比方说源时钟频率是目的时钟频率的三倍,不能采用握手,不能在信源对信号展宽,怎样在目的时钟域识别到这个信号的脉冲?fifo等存储器手段也不能用,而且没有随行的同步时钟信号

边沿检测同步器适用情况为:异步输入信号的脉冲宽度小于时钟周期时的同步电路(高速时钟域→低速时钟域)

上图中包括3条路径,对于路径1/2/3的数据路径分别为:

寄存器前门访问和后门访问的区别

前门访问通过总线来访问寄存器需要消耗仿真时间;而后门访问通过UVM DPI关联硬件寄存器路径,直接读取或修改硬件,不需要消耗仿真时间;

前门访问一般只能按字(word)进行读写,无法直接访问寄存器域;后门可以对寄存器或寄存器域进行读写;

实现1+2+3+4+.......

module Sum_n(input clk,rst_n,
input en,//单脉冲有效信号;
input [10:0]data_in,
output reg [29:0]sum_n,
output reg D_en//高电平表示和有效;
);
reg [10:0]data_buf;//data_1,
reg [1:0]state;
parameter Wait_signal = 2'b00,judge_data = 2'b01,data_sub = 2'b11,clr_en = 2'b10;
always@( posedge clk )beginif( !rst_n )beginsum_n <= 0;D_en <= 0;state <= Wait_signal;endelsebegincase ( state )Wait_signal : begin//默认态if( en )begindata_buf <= data_in;state <= judge_data;endelsestate <= Wait_signal;endjudge_data : begin//判决相加态if( data_buf >= 1'b1 )beginsum_n <= sum_n + data_buf;state <= data_sub;endelsebegin//sum_n <= 0;D_en <= 1;state <= clr_en;endenddata_sub : begin//减1态data_buf <= data_buf - 1'b1;state <= judge_data;endclr_en : begin//清零态D_en <= 0;state <= Wait_signal;endendcaseendend
endmodule

异步跨时钟域处理

对于单bit数据,可以采用打两拍的方式,但是这种方式只能适用于从慢时钟到快时钟;对于从快到慢的跨时钟域处理,需要用到脉冲同步器,如下所示:

module edge_detect(input sclk_1,//100Minput sclk_2,//50Minput p_in,output p_out);reg p_in_reg=0;reg dly1,dly2,dly3;wire mux_2;//组合逻辑产生毛刺,p_in没有和sclk_1 同步assign mux_2 = (p_in==1'b1)? (~p_in_reg):p_in_reg;always @(posedge sclk_1)p_in_reg <= mux_2;always @(posedge sclk_2){dly3,dly2,dly1} <= {dly2,dly1,p_in_reg};//流水移位赋值assign p_out = dly3 ^ dly2;endmodule

对于多bit数据,一般采用异步fifo来实现,也可以使用握手协议,但是握手效率低,适用于低速的情况;

采用握手机制:发送域现将数据锁存在总线上,随后发送一个req信号给接受域;接受域在检测到req信号后,锁存总线数据,并送回一个有效的ack信号表示读取完成应答;检测到应答信号ack后,撤销req信号,接受域在检测到req撤销后也相应撤销ack信号,完成一次正常的握手信号;

module handshake(input clk,                 //50MHZ时钟input rst_n,               //复位信号input req,                //数据发送请求信号input [15:0]data_in,        //数据输入output reg ack,            //应答信号output [15:0]data_out
);reg req1,req2,req3;                //req输入同步信号
reg [15:0]data_in_r;                //输入数据寄存器
wire pos_req1,pos_req2;
//---------通过三级寄存器同步异步输入信号req--------
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginreq1 <= 1'b0;req2 <= 1'b0;req3 <= 1'b0;endelse beginreq1 <= req;req2 <= req1;req3 <= req2;end
end
//--------------检测req1、req2的上升沿---------------
assign pos_req1 = req1 && ~req2;
assign pos_req2 = req2 && ~req3;
//----------在检测到pos_req1上升沿时,锁存数据-------
always@(posedge clk or negedge rst_n)beginif(!rst_n)begindata_in_r <= 16'd0;endelse beginif(pos_req1)begin//检测到上升沿,发送数据data_in_r <= data_in;endend
end
assign data_out = data_in_r;
//----------在检测到pos_req2上升沿时,发出ack应答信号,表示数据已经锁存-------
//----------检测req信号,如果req信号取消,则ack也取消-----------------------
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginack <= 1'b0;endelse beginif(pos_req2)beginack <= 1'b1;endelse if(!req)beginack <= 1'b0;endend
end
endmodule

parameter与define的区别

parameter声明和作用于模块内部,可以在调用模块时进行参数传递
define是全局作用,从编译器读到这条指令开始到编译结束都有效,或者遇到`undef命令使之失效;

如何验证一个异步FIFO?

验证分为验证场景和验证平台。验证场景如表所示:

注:在验证复位场景时,完整的复位验证应当包含以下情形的复位:

初始复位:在验证激励施加之前对读、写指针的复位,可以在driver中完成。

写复位:在FIFO写入过程中对写时钟域信号复位;在FIFO读出过程中对写时钟域信号复位。

读复位:在FIFO读出过程中对读时钟域信号复位;在FIFO写入过程中对读时钟域信号复位。

随机复位:任意情形下的随机复位。

在完成验证平台和验证场景的设计后,还需添加断言用于检查部分时序,所构建的断言应当包括以下点:

(1)检查复位时所有指针和满/空信号是否都处于低电平状态。

(2)当fifo读计数为0时,检查fifo_empty是否被置位。

(3)当fifo写计数大于FIFO宽度时,检查fifo_full是否被置位。

(4)检查如果fifo已满,并且尝试写入时写入指针不会更改。

(5)检查如果fifo已空,并且尝试读出时读指针不会更改。

(6)有一个属性会在尝试fifo写满时发出警告。

(7)有一个属性会在尝试fifo读空时发出警告。

(8)确保在WRITE模式下,写输入指针处于已定义状态(0或1),它不应为X态.同样适用于READ模式。

 什么是线与逻辑?

线与是指两个输出信号相连可以实现与的功能;在硬件上需要用OC门来实现,由于OC门可能使灌电流过大而烧坏逻辑门,需要在输出端口加上一个上拉电阻;

看下面代码复位为什么会失败?

reg rst_n;
reg f0_rst_n;
reg f1_rst_n;
wire rst_n_out;
always @(posedge clk)
beginf0_rst_n <= rst_n;f1_rst_n <= f0_rst_n;
endrst_n_out = rst_n | f0_rst_n | f1_rst_n;

f0_rst_n,f1_rst_n在被赋值以前都是x态,该代码的本意是将复位信号展宽,但是由于X态的存在会将或门的复位信号变为X态从而导致复位失败;

C语言实现斐波那契数列

int fibo1(int n)
{if (n == 1 || n==2){return 1;}return fibo1(n-2)+fibo1(n - 1);}

FPGA校招笔试题分析相关推荐

  1. IC/FPGA校招笔试题分析(三)

    还有1天就要进行某瓦科技的面试了,今天晚上赶紧复习下上次它的笔试题: 1.一个四位十六个状态的格雷码计数器,起始值为1001,经过100个时钟脉冲作用之后的值为(). 首先,算出100个脉冲后跑了多少 ...

  2. IC/FPGA校招笔试题分析(四)再看Moore状态机实现序列检测器

    参加了几次笔试,发现序列检测器是常考的内容,而之前认为序列检测器真的很简单,但是这次X疆的笔试题做完之后,我怀疑自己了. 画状态转移图的时候,我开始犹豫了,我怕我会没考虑全,甚至有点晕. 人家又问: ...

  3. IC/FPGA校招笔试题分析(二)任意切换的时钟分频电路

    今天的笔试题是某芸科技的现场笔试题,数字前端的笔试题,要求很简单,就是现场写出代码实现: 任意切换1-8分频,且无论奇分频还是偶分频,占空比均为50%,我至今仍然认为,在那种紧张且时间有限的情况下(本 ...

  4. IC/FPGA校招笔试题分析(一)

    某发科的一个题目,仅仅给出下面一个电路图,让你画出Q1,Q2以及Q3的波形,并描述电路功能. 可以看出,这个电路很简单(可tm的当时就是没做出来),我当时疑惑的是初值是什么,输入初值是什么? 可想想和 ...

  5. IC/FPGA笔试/面试题分析(七)建立时间和保持时间类型考题汇总分析

    自从召集2020届校招同行加入新建立的"IC/FPGA校招笔试面试交流群",见识到了很多关于建立时间和保持时间分析的题目,在为别人解答疑惑,以及别人为自己解答疑惑的同时,自己对于知 ...

  6. IC/FPGA笔试/面试题分析(八)近期IC/FPGA笔试面试讨论群题目汇总解析

    背景:IC前端设计/FPGA笔(面)试交流群,欢迎同行加入 自从开始邀请同行加入笔试面试交流群之后,目前已经有40多位同行加入,大家踊跃发言,各抒己见,让各自受益匪浅. 今天的这篇博文是将近期部分题目 ...

  7. 小米运维部14年校招笔试题A的个人答案

    15年准备实习生面试时答的题,仅供参考 具体题目详见  http://www.tuicool.com/articles/eYRZBr http://noops.me/?p=1154 一.linux基础 ...

  8. 凑硬币(58同城2017校招笔试题)

    凑硬币(58同城2017校招笔试题) 暴力破解,循环递归实现,代码如下: /** * 暴力破解,循环递归,找出了所有可能的组合并进行了存储,* 在循环递归的时候,因为选取的分类相互是有重叠的,生成的递 ...

  9. 剑指Offer——京东校招笔试题+知识点总结

    剑指Offer--京东校招笔试题+知识点总结 笔试感言 经过一系列的笔试,发觉自己的基础知识还是比较薄弱的,尤其是数据结构和网络,还有操作系统.工作量还是很大的.做到精确制导的好方法就是在网上刷题,包 ...

最新文章

  1. SAP MM 特性设置问题导致PR审批策略不对之分析
  2. KeUserModeCallback用法详解
  3. [caffe]深度学习之CNN检测object detection方法摘要介绍
  4. 二层交换机可以划分vlan吗_二层交换机上,属于不同VLAN的PC该如何通信
  5. QTextCodec中的setCodecForTr等终于消失了 (Qt5)
  6. java kafka 消费_java编程之Kafka_消费者API详解
  7. 所选驱动器不再有效,继续安装之前,请先检查安装路径的设置
  8. 整理一份程序员常用的各类工具、技术站点
  9. GCD LCM UVA - 11388 (思维。。水题)
  10. 面向对象编程(OOP)特性 类和对象
  11. div不继承父类样式_Java三大特性之继承
  12. gtk窗口和标签控件范例代码
  13. 基于STM32F103C8T6 HAL库 TM7705数据读取
  14. web前端开发初学者,html的介绍及常用标签
  15. 人脑VS机器? AI时代经济决策的机遇与挑战?
  16. 原神申鹤四星武器选哪个
  17. mac添加Chrome插件的方法
  18. java神雕侠侣1古墓情缘游戏攻略_《神雕侠侣》手游古墓秘境1到5关详细攻略
  19. python画椭圆的逻辑_Python plt画椭圆
  20. Java 中 字符串 1234 怎么转成 int?

热门文章

  1. linux下修复windows10引导,ubuntu下 修复win10引导
  2. hive 中文字符过滤_hive中文字符乱码 解决方法【转】
  3. 图基准数据集(OGB)
  4. 服务器维修故障诊断思路大全
  5. 记录:mac和win共享磁盘(同一局域网)
  6. 从DataSet 导出到Excel(是DataSet中的每个DataTable对应每个Sheet)
  7. HTML实现公告文字滚动效果
  8. OpenCV进阶(8)性别和年龄识别
  9. CentOS8 源码编译安装 lamp环境 (apache24 + php7.3 + mysql57)
  10. php 根据日期获取星座,js 根据日期获取星座名称