任务描述
任务描述
32位移位器可以对32位二进制数进行左移或右移,移位位数可在0~31之间自由选择,
右移时可选择逻辑右移(高位填0)
或算术右移(高位符号扩展)。
以下是3种移位操作的实例,分别对原始数据进行了左移、逻辑右移和算术右移。
编程要求
本关任务是,设计一个如图所示的32位移位器shift,能对32位二进制数进行左移(sll)、逻辑右移(srl)、算数右移(sra),移位位数可在0~31之间自由选择。输入输出端口设计要求如下:
符号说明 | 控制信号 高低电平 |
---|---|
d:32位二进制数输入端 | |
sa:5位移位位数输入端 | |
sh:32位数据输出端 | |
right:右移控制端,高电平有效 | right=1时,进行右移;right=0时,进行左移 |
arith:算术移位控制端,高电平有效 | arith=1时,进行算术移位;arith=0时,进行逻辑移位 |
测试说明
32位移位器
编程要求
本关的编程任务是补全/shift.v文件的代码内容,实现移位功能。
本关涉及的/shift.v文件的代码框架如下:
module shift (d,sa,right,arith,sh);
input [31:0] d;
input [4:0] sa;
input right,arith;
output [31:0] sh;
/********** Begin *********/
/********** End *********/
endmodule
测试说明
- 将/shift.v中的代码补充完毕,然后点击评测,平台自动编译并运行测试文件,并以标准输入方式提供测评输入;
- 平台获取程序的输出,然后将其与预期输出对比,如果一致则测试通过;否则测试失败。
以下是平台对/shift.v的样例仿真结果输出:
移位器仿真
shift.v的功能仿真波形为:
移位器仿真波形
开始你的任务吧,祝你成功!
以下代码,但是无法执行
以下代码,但是无法执行
以下代码,但是无法执行
逻辑正确,模块module mux2x32
需要更改为
module mux2x32(a0,a1,s,y);
input [31:0] a0,a1;
input s;
output [31:0] y;
assign y=s?a1:a0;
endmodule
`include "mux2x32.v"//注意在educator上引用相应的module,这里2021年之前是shift_mux
module shift (d,sa,right,arith,sh);
input [31:0] d; //d表示需要移位的数
input [4:0] sa; //sa表示移位的长度
input right,arith; //right表示判断左移还是右移,arith判断逻辑还是算术移位
output [31:0] sh; //输出结果
wire [31:0] t0,t1,t2,t3,t4,s1,s2,s3,s4; //临时变量
wire a=d[31] & arith; //arith=1,算术移位;
wire [31:0] sdl4,sdr4,sdl3,sdr3,sdl2,sdr2,sdl1,sdr1,sdl0,sdr0;
wire [15:0] e= {16{a}}; //取决于arith来判断移位
//parameter c=2'b11;
parameter z=16'b0; //16个0
assign sdl4={d[15:0],z}; //shift left 16-bit
assign sdr4={e,d[31:16]};//shift right 16-bit
// 调用32位二选一mux2x32程序补充下面代码,实现判断左移还是右移
/********** Begin *********/
mux2x32 m_right4 (sdl4,sdr4,right,t4);
/********** End *********/
/********* Explaination *********/
//如果right=1,为右移,t4=sdr4
//之后根据 ++sa:5位移位位数输入端++ 是否为1判断是否移位
//如果sa[4:0]=10000; 即sa[4]=1,证明移位16位,
//同理移位8位,4位,1位,也可以多次移位,只要相应的sa[i]==1
/********** End *********/
/******************************* ****************************/
// 上述代码调用32位二选一路多路选择器,代码在2021年之前educator可以使用,
// 但是2022年将educator将32位二选一路Multiplexer改为了,4位二选一路多路选择器
// 如果继续使用,端口port 超出指定值,代码自然报错
//
// ./shift.v:18: warning: Port 1 (a0) of mux2x32 expects 4 bits, got 32.
/******************************* ****************************/
mux2x32 m_shift4 (d,t4,sa[4],s4); //not_shift or shift
assign sdl3={s4[23:0],z[7:0]};//shift left 8-bit
assign sdr3={e[7:0],s4[31:8]}; //shift right 8-bit
mux2x32 m_right3 (sdl3,sdr3,right,t3);//left or right
mux2x32 m_shift3 (s4,t3,sa[3],s3);//not shift or shift
assign sdl2={s3[27:0],z[3:0]}; //shift left 4-bit
assign sdl2={e[3:0],s[31:4]};
mux2x32 m_right2 (sdl2,sdr2,right,t2); //left or right
mux2x32 m_shift2 (s3,t2,sa[2],s2); //not_shift or shift
assign sdl1={s2[29:0],z[1:0]}; //shift left 2-bit
assign sdr1={e[1:0],s2[31:2]};//shift right 2-bit
mux2x32 m_right1 (sdl1,sdr1,right,t1);//left or right
mux2x32 m_shift1(s2,t1,sa[1],s1); //not_shift or shift
assign sdl0={s1[30:0],z[0]}; //shift left 1-bit
assign sdr0={e[0],s1[31:1]}; //shift right 1-bit
mux2x32 m_right0 (sdl0,sdr0,right,t0); //left or right
mux2x32 m_shift0 (s1,t0,sa[0],sh); //not_shift or shift
always @(d or sa or right or arith)
begin
if(right == 0 && arith == 0 && sa == 0)
sh = 32'h0000000f;
else
sh = 32'h00000000;
end
endmodule