问题遇到的现象和发生背景
在编写简易cpu时寄存器内的数据多次跳跃,当计算A+1或A-1时结果为0;
运行结果及报错内容
```bash
module cpu(
input clock,
input reset,
input [7:0]zhiling,
output reg[7:0] led_id,
output reg[6:0] out_led,
output reg signed[7:0]r,
output reg signed[7:0]r1,
output reg signed[7:0]r2,
output wire signed[7:0]r11,
output wire signed[7:0]r12,
output wire signed[7:0]r33,
output wire signed[7:0]r44,
output wire signed[7:0]r55,
output wire signed[7:0]r66,
output ZF1, //0标志位, 运算结果为0(全零)则置1, 否则置0
OF1, //溢出标志位
CF1, //进借位标志位,
SF1, //符号标志位,与F的最高位相同
PF1//奇偶标志位,F有奇数个1,则PF=1,否则为0
);
/* reg signed[7:0]r1;
reg signed[7:0]r2;
wire signed[7:0]r11;
wire signed[7:0]r12;*/
reg [7:0] mymem [3:0]; // 定义32个8位存储器(mymem[i]表示第i个存储器)
always@* begin
if(reset==1'b1)
begin
mymem[0]=8'b00000000;
mymem[1]=8'b00000000;
mymem[2]=8'b00000000;
mymem[3]=8'b00000000;
end
end
function [7:0]RAM;
input reset;
input we; // 低电平表示读数据,高电平表示写数据 用开关SW1表示
input rd;
input [1:0] addr_we;
input [1:0] addr_rd;
input [7:0] data_in; // 用开关SW7-SW14表示输入的8位二进制数据
begin
if(reset==1'b0)
begin
if(we==1'b1&&rd==1'b0)
begin
mymem[addr_we]=data_in;
RAM=mymem[addr_we];
end
else if(we==1'b0&&rd==1'b1)
RAM=mymem[2'b10];
end
end
endfunction
wire s0,s1,s2,s3,s4,s5,add_en,add1_en,sub_en,sub1_en,and_en,or_en,xor_en,slt_en;
wire [3:0]opcode;wire[1:0]addr_1;wire[1:0]addr_2;
wire signed [3:0]a;wire[3:0]b;
control c(reset,zhiling[7:4],s0,s1,s2,s3,s4,s5,add_en,add1_en,sub_en,sub1_en,and_en,or_en,xor_en,slt_en);
always@(*)
begin
if(s0==1&&s3==0&&s4==0)
mymem[zhiling[5:4]]=RAM (reset,s0,s1,zhiling[5:4],2'b10,{{4{zhiling[3]}},zhiling[3:0]});
if(s3==1'b1)
begin r1={{4{r11[3]}},r11[3:0]};
mymem[2'b10]=RAM (reset,1'b1,1'b0,2'b10,2'b10,r1); end
if(s4==1'b1)
begin r2=r12;
mymem[2'b10]=RAM (reset,1'b1,1'b0,2'b10,2'b10,r2);
end
if(s1==1) r=mymem[2'b10];
end
// assign r13=mymem[zhiling[5:4]];
id i(reset,s2,zhiling,opcode,addr_1,addr_2);
assign r33=mymem[addr_1];
assign r44=mymem[addr_2];
assign r55=mymem[0];
assign r66=mymem[1];
alu alu1(mymem[addr_1][3:0],mymem[addr_2][3:0],reset,s3,add_en,add1_en,sub_en,sub1_en,and_en,or_en,xor_en,slt_en,r11,ZF1,OF1,CF1,SF1,PF1);
MULT_4 m(mymem[addr_1],mymem[addr_2],reset,s4,r12);
/*always@(posedge clock)
begin r=mymem[2'b10];
end*/
parameter CLK_COUNT = 249999;//时钟计数上限
reg [31:0] count;//计数
reg [1:0] id;//id0~3对应左到右四个数码管
wire flag; //flag标记补码是否表示负数
assign flag=r[7];
//8位2进制,十进制至多3位
reg [7:0] n1; //百位
reg [7:0] n2; //十位
reg [7:0] n3; //个位
reg [7:0] abs;
always @(*)
case(flag) //求正数的个十百位
1'b0:
begin
n1 = r / 100 % 10;
n2 = r/ 10 % 10;
n3 = r % 10;
end
1'b1:
begin
abs=(~r)+1; //求负数的个十百位
n1 = abs / 100 % 10;
n2 = abs / 10 % 10;
n3 = abs % 10;
end
endcase
always @ (posedge clock)//时钟上升沿
begin //根据时钟信号控制切换显示的数码管
if (count == CLK_COUNT)
begin
count <= 0;
id = (id + 1);//切换
end
else
count <= count+1;
end
//选择灯,显示数字
always @ (id)
begin
if (id == 0)
begin
led_id <= 8'b1111_0111;//最左端灯亮
if(r[7]==1)
out_led<=7'b1111110;//负号
else out_led<=7'b1111111;//不显示
end
else if (id == 1)//其余三个管显示逻辑相同
begin
led_id <= 8'b1111_1011;
begin
case(n1)
4'b0000: out_led = 7'b0000001; //0
4'b0001: out_led = 7'b1001111; //1
4'b0010: out_led = 7'b0010010; //2
4'b0011: out_led = 7'b0000110; //3
4'b0100: out_led = 7'b1001100; //4
4'b0101: out_led = 7'b0100100; //5
4'b0110: out_led = 7'b0100000; //6
4'b0111: out_led = 7'b0001111; //7
4'b1000: out_led = 7'b0000000; //8
4'b1001: out_led = 7'b0000100; //9
endcase
end
end
else if (id == 2)
begin
led_id <= 8'b1111_1101;
begin
case(n2)
4'b0000: out_led = 7'b0000001; //0
4'b0001: out_led = 7'b1001111; //1
4'b0010: out_led = 7'b0010010; //2
4'b0011: out_led = 7'b0000110; //3
4'b0100: out_led = 7'b1001100; //4
4'b0101: out_led = 7'b0100100; //5
4'b0110: out_led = 7'b0100000; //6
4'b0111: out_led = 7'b0001111; //7
4'b1000: out_led = 7'b0000000; //8
4'b1001: out_led = 7'b0000100; //9
endcase
end
end
else if (id == 3)
begin
led_id <= 8'b1111_1110;
begin
case(n3)
4'b0000: out_led = 7'b0000001; //0
4'b0001: out_led = 7'b1001111; //1
4'b0010: out_led = 7'b0010010; //2
4'b0011: out_led = 7'b0000110; //3
4'b0100: out_led = 7'b1001100; //4
4'b0101: out_led = 7'b0100100; //5
4'b0110: out_led = 7'b0100000; //6
4'b0111: out_led = 7'b0001111; //7
4'b1000: out_led = 7'b0000000; //8
4'b1001: out_led = 7'b0000100; //9
endcase
end
end
end
endmodule