You are given a module my_dff8 with two inputs and one output (that implements a set of 8 D flip-flops). Instantiate three of them, then chain them together to make a 8-bit wide shift register of length 3. In addition, create a 4-to-1 multiplexer (not provided) that chooses what to output depending on sel[1:0]: The value at the input d, after the first, after the second, or after the third D flip-flop. (Essentially, sel selects how many cycles to delay the input, from zero to three clock cycles.)
您得到了一个具有两个输入和一个输出的模块my_dff8(它实现了一组8D触发器)。实例化其中三个,然后将它们链接在一起,形成一个长度为3的8位宽移位寄存器。此外,创建一个4对1多路复用器(未提供),根据sel[1:0]选择输出内容:输入d、第一个、第二个或第三个d触发器之后的值。(本质上,sel选择延迟输入的周期,从零到三个时钟周期。)
就是实例化三个my_dff8模块,然后把输出按图片的连接方式连接一个八选一多路器。
八选一多路器实际上就是按照sel的值,在几个输入口里面(0-3),选择一个的值输出,
实际上可以用一个case语句来实现
case(值)
值1:执行语句;
值2:执行语句;
default:执行语句;
endcase
注意case语句一定要用在always块里面,
所以代码如下
module top_module (
input clk,
input [7:0] d,
input [1:0] sel,
output reg [7:0] q
);
wire [7:0] mdf1_qout_mdf2_din;
wire [7:0] mdf2_qout_mdf3_din;
wire [7:0] mdf3_qout;my_dff8 my_dff8_1(
.clk(clk),
.d(d),
.q(mdf1_qout_mdf2_din)
);
my_dff8 my_dff8_2(
.clk(clk),
.d(mdf1_qout_mdf2_din),
.q(mdf2_qout_mdf3_din)
);
my_dff8 my_dff8_3(
.clk(clk),
.d(mdf2_qout_mdf3_din),
.q(mdf3_qout)
);
always@(*)begin
case(sel)
2'b00:q <= d;
2'b01:q <= mdf1_qout_mdf2_din;
2'b10:q <= mdf2_qout_mdf3_din;
2'b11:q <= mdf3_qout;
default:;
endcase
end
endmodule
看起来很长,但弄懂原理之后都很简单。
然后注意在使用always@()内部设置激励信号的时候,里面不要用posedge clk,如果使用这个会导致和目标有一个时钟节拍的延迟,里面的信号最好使用*
always@(posedge clk)
always@(*)
这里简单说一下always的用法
always语句有两种触发方式。
第一种 电平触发
always @(a or b)
a、b均为变量,当其中一个发生变化时,下方的语句将被执行。
第二种 沿触发
always @(posedge clk or negedge rstn)
即当时钟处在上升沿或下降沿时,语句被执行。
always@(*):首先 * 的意思就代表了always模块里面的所有信号,模块内的任何一个信号发生变化,就会立刻执行。
这种变化包含以上两种触发方式,电平变化触发和沿触发都会执行语句,
所以 always@(posedge clk) 会等到clk上升沿的时候才触发
而 always@(*) 会在内部信号发生变化的立刻就触发