本文转载自:OpenFPGA
1、用状态机实现10010码的探测,如x=1001001000 z=0000100100(输出)
module check(rst_i,clk_i,data_i,data_o);input rst_i,clk_i;input data_i;output data_o;reg[3:0] current_state,next_state;parameter[3:0]idle="0000",state1="0001",state2="0010",state3="0100",state4="1000";always@(posedge clk_i or negedge rst_i)if (!rst_i)current_state<=idle;< span="">elsecurrent_state<=next_state;always@(current_state,data_i)case(current_state)idle : if (data_i==1)next_state=state1;else next_state=idle;state1: if (data_i==0)next_state=state2;else next_state=idle;state2: if (data_i==0)next_state=state3;else next_state=idle;state3: if (data_i==1)next_state=state4;else next_state=idle;state4: if (data_i==0)next_state=idle;else next_state=idle;endcaseassign data_o= (current_state==state4);endmodule
VHDL
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity check isport(rst_i :in std_logic;clk_i :in std_logic;data_i:in std_logic;data_o:out std_logic);end entity;--}} End of automatically maintained sectionarchitecture behave of check istype state is (state_a,state_b,state_c,state_d,state_e);signal current_state:state;signal next_state:state;begin--type state is (state_a,state_b,state_c,state_d);process(rst_i,clk_i)beginif rst_i='1' thendata_o<='0';< span="">current_state<=state_a;< span="">elsif rising_edge(clk_i) thencurrent_state<=next_state;< span="">end if;end process;process(current_state,data_i)begincase current_state iswhen state_a => if data_i='1' thennext_state<=state_b;< span="">elsenext_state<=state_a;< span="">end if;when state_b => if data_i='0' thennext_state<=state_c;< span="">elsenext_state<=state_a;< span="">end if;when state_c => if data_i='0' thennext_state<=state_d;< span="">elsenext_state<=state_a;< span="">end if;when state_d => if data_i='1' thennext_state<=state_e;< span="">elsenext_state<=state_a;< span="">end if;when state_e => if data_i='0' thennext_state<=state_a;elsenext_state<=state_a;< span="">end if;when others => null;end case;end;data_o <='1' when current_state = state_e else '0';end;
3、 用D触发器实现2倍分频的逻辑电路?
module divide2( clk , clk_o, reset);    input     clk , reset;    output   clk_o;    wire in; reg out ;    always @ ( posedge clk or posedge reset)if ( reset)out <= 0;elseout <= in;assign in = ~out;assign clk_o = out;      endmodule
4、 试用VHDL或VERILOG、ABLE描述8位D触发器逻辑。
module dff8(clk , reset, d, q);input        clk;input        reset;input  [7:0] d;output [7:0] q;reg   [7:0] q;always @ (posedge clk or posedge reset)if(reset)q <= 0;elseq <= d;endmodule
5、 给了reg的setup,hold时间,求中间组合逻辑的delay范围。
Delay < period - setup - hold
6、 写异步D触发器的verilog module
module dff8(clk , reset, d, q);input        clk;input        reset;input   d;output  q;reg q;always @ (posedge clk or posedge reset)if(reset)q <= 0;elseq <= d;endmodule
8、

R1反馈回到自身需要的时间为7(=1+ 5*1+T_setup)
R2反馈加到自身需要的时间为6(=1+2*1+2+T_setup)
显然,最小周期不能小于7,即T>=7。(否则,R1不能正确采样到其反馈值)
所以答案分别是:
1)1+5*1+2+1=9
2)1+5*1+2+1- T_skew = 8
3)1+5*1+2+1-T_skew = 5,但因为T>=7,所以Tmin=7
4)记T_skew = t2 - t1,
则正偏时,T_skew必须小于R1到R2的最小延时(不包括Tsetup),即T_skew<6(=1+3*1+2),以保证,r2采样到正确的值
负偏差时,T- (T_skew的绝对值)必须大于或等于R1到R2的最大延时9,即(T_skew的绝对值)<=t-9
综合一下,就是(9-T) ≤ T_skew < 6
系统时钟周期 Tclk>=Tco+T logic delay max+T2setup-Tskew
正偏时,不但要考虑T>=Tco+Tlogic+Tsu-Tskew(且只需在T<9的情况下考虑),还要考虑(tco+tlogic)min>Tskew+Thold(但这里Thold没给出就当作是零),否则会有数据冲突,使得R2不能正确采样前一周期从R1传来的值,所以就是Tskew<(tco+tlogic)min=6
所以正偏时,9-T≤ Tskew<6
负偏时,根据T>=Tco+Tlogic+Tsu-Tskew,就可以得到9-T≤ Tskew。
而不等式(Tco+Tlogic)min >Tskew+Thold,因Thold已经当作零,Tskew为负值,恒成立。
所以负偏时9-T≤ Tskew<=0
将两种请况综合就是9-T≤ Tskew<6< span="">
11、 用一个二选一mux和一个inv实现异或。(飞利浦-大唐笔试)
input a,b;output c;assign c=a?(~b):(b);
14、 写异步D触发器的verilog module。(扬智电子笔试)
module dff8(clk , reset, d, q);input clk;input reset;input [7:0] d;output [7:0] q;reg [7:0] q;always @ (posedge clk or posedge reset)if(reset)q <= 0;elseq <= d;endmodule
15、 用D触发器实现2倍分频的Verilog描述? (汉王笔试)
module divide2( clk , clk_o, reset); input clk , reset; output clk_o; wire in;reg out ; always @ ( posedge clk or posedge reset)if ( reset)out <= 0;elseout <= in;assign in = ~out;assign clk_o = out; endmodule
16、 饮料10分钱,硬币有5分、10分两种,投币一次或者两次,累计大于或者等于10分时,饮料弹出,有多余的硬币,也会弹出,由此可知,可以分为两个状态,一个是0分,一个是5分。累计的币值等于10分,则弹出饮料,找零0分;累计的币值为15分,则弹出饮料,找零5分。
状态转移图:

代码设计:


FIFO 是先入先出存储器的缩写,FIFO 控制器在数字系统中被大量使用,可以作为数据缓存
使用。时钟同步的FIFO 控制器接口如下图所示,主要接口信号定义如下:
RST_N:异步复位信号,当RST_N 为低电平时,FULL 输出‘0’,EMPTY 信号输出‘1’
电平,FIFO 指针指向0,FIFO 被清空;
CLK:时钟信号,输出信号与CLK 信号同步;
DATAIN:数据输入信号,8 位总线;
RD:读有效信号,高电平有效,当RD 位高时,在时钟信号CLK 的上升沿,DATAOUT 输
出一个8 位的有效数据;
WR:写有效信号,当WR 为高电平时,在CLK 的上升沿,从DATAIN 信号向存储器写入
一个8 位的有效数据;
DATAOUT:数据输出信号,8 位总线,在CLK 的上升沿,当RD 为高电平时,从FIFO 中
输出一个8 位的数据;
FULL:存储器写满标志信号,高电平时表示存储器中的数据已经写满;
EMPTY:存储器读空标志信号,高电平时表示存储器中的数据已经被读空了。
要求:用Verilog 写一个8x16 的FIFO,完成先入先出的功能,并且在FIFO读空时输出EMPTY
有效信号,读指针RP 不再移动;FIFO 写满时输出FULL 有效信号,并且即使WR 有效也
不再向存储单元中写入数据(写指针WP 不再移动)。
存储单元使用一个二维数组来建模。注意存储单元的地址在读或者写到最高地址时要能回到最低值。
module fifo_mem(data,clk,rstN,wrN,rdN,empty,full);inout [7:0] data;input clk,rstN,wrN,rdN;output empty,full;reg [4:0] _cntr,rd_cntr;wire [3:0] add;ram16X8 ram(.data(data),.addr(addr),.wrN(wrN),.oe(wrN));always @(posedge clk or negedge rstN)if(!rstN) wr_cntr<=0;else if (!wrN) wr_cntr<=wr_cntr+1;always @ (posedge clk or negedge rstN) if(!rstN) rd_cntr<=0; else if(!rdN) rd_cntr<=rd_cntr+1;assign addr=wrN?rd_cntr [3:0]: wr_cntr [3:0];assign empty=(wr_cntr [3:0] == rd_cntr [3:0])&&!(wr_cntr[4]^rd_cntr[4]);assign full=(wr_cntr [3:0] ==rd_cntr [3:0])&&(wr_cntr[4]^rd_cntr[4]);endmodule
18、 用你熟悉的设计方式设计一个可预置初值的7进制循环计数器,15进制的呢?
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;endendmodule