提示:左移实现×2功能。
d[7:0] | out[10:0] | |
d*1 | d | {3'b0,d} |
d*3 | d*(4-1) | (d<<2)-d |
d*7 | d*(8-1) | (d<<3)-d |
d*8 | d*8 | d<<3 |
module multi_sel
(
input wire [7:0] d ,
input wire clk ,
input wire rst ,
output reg input_grant,
output reg [10:0] out
);
reg [1:0] cnt;
reg [7:0] d_buff;
always@(posedge clk)begin
if(!rst)begin
cnt <= 2'b0;
end else if(cnt == 3)begin
cnt <= 2'b0;
end else begin
cnt <= cnt + 1;
end
end
always@(posedge clk)begin
if(!rst)begin
d_buff <= 8'd0;
end else if(cnt == 0)begin
d_buff <= d;
end else begin
d_buff <= d_buff;
end
end
always@(posedge clk)begin
if(!rst)begin
out <= 11'b0;
end else begin
case(cnt)
0 : out <= {3'b0,d};
1 : out <= (d_buff<<2) - d_buff;
2 : out <= (d_buff<<3) - d_buff;
3 : out <= d_buff<<3;
default : out <= 11'b0;
endcase
end
end
always@(posedge clk)begin
if(!rst)begin
input_grant <= 1'b0;
end else if(cnt == 0)begin
input_grant <= 1'b1;
end else begin
input_grant <= 1'b0;
end
end
endmodule
`timescale 1ps/1ps
module tb();
reg clk ;
reg rst ;
reg [7:0] d ;
wire[10:0] out ;
wire input_grant;
reg [7:0] clk_cnt;
reg [1:0] cnt_buf;
reg clk_cnt_en;
always begin
#2500 clk = ~clk;
end
initial begin
clk = 1;
rst = 1;
clk_cnt_en = 0;
repeat(5)@(posedge clk);
rst = 0;
d = 8'd143;
repeat(4)@(posedge clk);
#1 rst = 1;
d_case(d,8'd143 );
#15000 d_case(d,8'd7 );
#25000 d_case(d,8'd6 );
#5000 d_case(d,8'd128 );
#5000 d_case(d,8'd129 );
#30000 clk_cnt_en = 1;
repeat(257)begin
#20000 d_case(d,clk_cnt);
end
repeat(10000)begin
#5000 d_case(d,{$random}%8'hff);
end
repeat(10)@(posedge clk);
$finish();
end
always@(multi_sel.d_buff)begin
if(clk_cnt == 255)begin
clk_cnt <= 1;
end else if(clk_cnt_en)begin
clk_cnt <= clk_cnt + 1'b1;
end else begin
clk_cnt <= 0;
end
end
task d_case;
output [7:0] a;
input [7:0] b;
a = b;
endtask
always@(posedge clk)begin
cnt_buf <= multi_sel.cnt;
end
always@(cnt_buf)begin
if((cnt_buf == 0) && (rst == 1))begin
if(out == {3'b0,multi_sel.d_buff});
else begin
$display($realtime,",*1 error:cnt_buf = %d;d_buff*1 = %d;out = %d",cnt_buf,{3'b0,multi_sel.d_buff},out);
end
end else if((cnt_buf == 1) && (rst == 1))begin
if(out == ((multi_sel.d_buff << 2)-multi_sel.d_buff));
else begin
$display($realtime,",*3 error:cnt_buf = %d;d_buff*3 = %d;out = %d",cnt_buf,(multi_sel.d_buff << 2)-multi_sel.d_buff,out);
end
end else if((cnt_buf == 2) && (rst == 1))begin
if(out == ((multi_sel.d_buff << 3)-multi_sel.d_buff));
else begin
$display($realtime,",*7 error:cnt_buf = %d;d_buff*7 = %d;out = %d",cnt_buf,(multi_sel.d_buff << 3)-multi_sel.d_buff,out);
end
end else if((cnt_buf == 3) && (rst == 1))begin
if(out == (multi_sel.d_buff << 3));
else begin
$display($realtime,",*8 error:cnt_buf = %d;d_buff*8 = %d;out = %d",cnt_buf,multi_sel.d_buff << 3,out);
end
end
end
initial begin
$fsdbDumpfile("tb.fsdb");
$fsdbDumpvars(0,tb);
end
multi_sel U0 (
.clk (clk ),
.rst (rst ),
.d (d ),
.out (out ),
.input_grant(input_grant)
);
endmodule
因篇幅问题不能全部显示,请点此查看更多更全内容