经典组合和数字电路的设计
硬件描述的层次
门级(gate-level)、寄存器传输级(RTL-level)、行为级
组合逻辑电路
不需要有时钟和复位信号,由当前输入决定当前输出,且输出不受上一次输出影响
时序逻辑电路
有限状态机
1)moore型状态机:状态机的输出只与当前的状态有关。
moore状态机在时钟脉冲的有限个门延时后,输出达到稳定。输出会在一个完整的时钟周期内保持稳定态,即使在改时钟内输入信号变化了,输出信号也不会变化。输入对输出的影响要到下一个时钟周期才能反应出来。把输入和输出分开。
2)mealy型状态机:状态机的输入不仅与当前的状态有关,还与当前的输入有关。
mealy状态机由于输出直接受到输入影响,而输入可以在时钟周期的任意时刻变化,使得输出状态比moore状态机的输出状态提前一个周期到达。输入信号的噪声可能会出现在输出信号上。
对于同一电路,使用moore状态机设计可能会比mealy状态机多出一些状态。
同步FIFO
module sync_fifo(clk,rst,write_enable,read_enable,write_data,read_data,empty,full);
input clk;
input rst;
input write_enable;
input read_enable;
input [7:0] write_data;
output [7:0] read_data;
output empty;
output full;
reg [7:0] mem[15:0];
reg [7:0] read_data;
wire [3:0] w_addr_a, r_addr_a;
reg [4:0] w_addr_e, r_addr_e;
assign w_addr_a = w_addr_e[3:0];
assign r_addr_a = r_addr_e[3:0];
always @(posedge clk or negedge rst) begin
if(!rst) r_addr_e <= 5'b0;
else begin
if(empty == 0 && read_enable == 1) begin
read_data <= mem[r_addr_a];
r_addr_e <= r_addr_e + 1;
end
end
end
always @(posedge clk or negedge rst) begin
if(!rst) w_addr_e <= 5'b0;
else begin
if(full == 0 && write_enable == 1) begin
mem[w_addr_a] <= write_data;
w_addr_e <= w_addr_e + 1;
end
end
end
assign empty = (r_addr_e == w_addr_e) ? 1 : 0;
assign full = (r_addr_e[4] != w_addr_e[4] && r_addr_e[3:0] == w_addr_e[3:0]) ? 1 : 0;
endmodule
异步fifo
1)对于是否满状态的判断:先要对读指针(属于读时钟域)在写时钟域进行采样,然后才能与写指针进行比较,如果写指针赶上了读指针,说明已经写满,写操作必须暂停。
2)二进制不适合做空满判断:二进制读指针在增减时,经常发生多位突变,比如六位地址111111会在下一时刻变成000000,在实际电路中,这个变化过程要持续很长一段时间,会经历6个状态转移。由于写时钟与读时钟域不同,异步的写时钟很可能会在状态不稳定的中间某个状态采样,这样就会得到错误的读指针,进而做出错误的状态判断,导致系统异常(亚稳态)。由于多位同时突变,发生错误的可能性更大。
在中间态采样时这个是不可避免的(异步系统的缺陷),若要即使在中间状态采样也不影响空满状态的判断,则需要采样格雷码的编码方式(每次只有一个bit发生改变)。当只有一个改变时,结果不外乎两种:递增前原指针和递增后新指针。当采样到原指针时假设采样读指针,最坏的情况就是把“不满”判断为”满“,使得原本被允许的写操作禁止,不会产生逻辑错误,只是带来了写操作的延。对于写指针类似。
格雷码
1.消除多比特同步的判断问题,减少亚稳态
2.降低功耗