Я считаю, что msbit выполняет бит на своих собственных покрытиях без знака, а для подписанного вы смотрите, различаются ли перенос в msbit и исполнение.
5-0 не переполняется, потому что результат соответствует количеству доступных битов. Так же, как 15-1 не переполняет 4-битную систему для чисел со знаком.
5 - 0 = 0101 + 1111 + 1
1
0101
+1111
=====
11111
0101
+1111
=====
0101
поэтому 5 - 0, безусловно, выполняет 1, так как это вычитание, которое не является переполнением
15 - 1 = 1111 + ~1 с переносом в наборе
1
1111
1110
====
11111
1111
1110
====
1110
вычитание с выходом 1 не является беззнаковым переполнением, как вы заявили
Аналогично -1 - 1 = 1111 + ~ 1 с установленным битом переноса.
11111
1111
1110
====
1110
перенос в последний бит - это 1, перенос - это 1, они совпадают, нет переполнения со знаком.
8 + 8 = 1000 + 1000 с переносом в чистоте
0
1000
+1000
=====
10000
1000
+1000
=====
0000
беззнаковое переполнение.
хммм 4 + 4
0
0100
+0100
=====
01000
0100
+0100
=====
1000
unsigned add выполнение равно 0, это не беззнаковое переполнение. но это переполнение со знаком, потому что перенос в msbit и выполнение отличаются. +4 + +4 = +8, в 4-битной системе со знаком вы не можете представить +8, поэтому переполнение со знаком является точным.
Независимо от того, сколько битов, странные числа - это все нули и единица, а остальные нули, 0 и 8 или -8 для 4-битной системы.
Создайте диаграмму с 2-, 3- или 4-битными числами во всех комбинациях и вручную просмотрите их все, чтобы убедиться, что они имеют смысл. все, что вы найдете, будет масштабироваться независимо от того, сколько битов в ширину, 100-битный сумматор работает как 10-битный сумматор...
add C V unsigned signed
00 + 00 = 000 0 0 0 + 0 = 0 0 + 0 = 0
00 + 01 = 001 0 0 0 + 1 = 1 0 + 1 = 1
00 + 10 = 010 0 0 0 + 2 = 2 0 + -2 = -2
00 + 11 = 011 0 0 0 + 3 = 3 0 + -1 = -1
01 + 00 = 001 0 0 1 + 0 = 1 1 + 0 = 1
01 + 01 = 010 0 1 1 + 1 = 2 1 + 1 = 2 signed cannot represent a +2
01 + 10 = 011 0 0 1 + 2 = 3 1 + -2 = -1
01 + 11 = 100 1 0 1 + 3 = 4 1 + -1 = 0 unsigned cannot represent +4
10 + 00 = 010 0 0 2 + 0 = 2 -2 + 0 = -2
10 + 01 = 011 0 0 2 + 1 = 3 -2 + 1 = -1
10 + 10 = 100 1 1 2 + 2 = 4 -2 + -2 = -4 neither +4 nor -4 will fit in 2 bits
10 + 11 = 101 1 1 2 + 3 = 5 -2 + -1 = -3 neither +4 nor -3 will fit in 2 bits
11 + 00 = 011 0 0 3 + 0 = 3 -1 + 0 = -1
11 + 01 = 100 1 0 3 + 1 = 4 -1 + 1 = -2 +4 does not fit in 2 bits
11 + 10 = 101 1 1 3 + 2 = 5 -1 + -2 = -3 neither +5 nor -3 fit in 2 bits
11 + 11 = 110 1 0 3 + 3 = 6 -1 + -1 = -2 6 does not fit in 2 bits
sub
00 - 00 = 100 0 0
00 - 01 = 011 1 0 0 - 1 = -1 -1 does not fit in an unsigned result
00 - 10 = 010 1 1 0 - 2 = -2 0 - -2 = +2
00 - 11 = 001 1 0 0 - 3 = -3
01 - 00 = 101 0 0
01 - 01 = 100 0 0
01 - 10 = 011 1 1 1 - 2 = -1 1 - -2 = 3
01 - 11 = 010 1 1 1 - 3 = -2 1 - -1 = 2
10 - 00 = 110 0 0
10 - 01 = 101 0 1 -2 - 1 = -3
10 - 10 = 100 0 0
10 - 11 = 011 1 0 2 - 3 = -1
11 - 00 = 111 0 0
11 - 01 = 110 0 0
11 - 10 = 101 0 0
11 - 11 = 100 0 0
Код, который сгенерировал вышеуказанное
printf("add\n");
for(ra=0;ra<4;ra++)
{
for(rb=0;rb<4;rb++)
{
rd=(ra&1)+(rb&1);
rc=ra+rb;
rd=(rd>>1)&1;
re=(rc>>2)&1;
if(re) c=1; else c=0;
if(rd!=re) v=1; else v=0;
if(ra&2) printf("1"); else printf("0");
if(ra&1) printf("1"); else printf("0");
printf(" + ");
if(rb&2) printf("1"); else printf("0");
if(rb&1) printf("1"); else printf("0");
printf(" = ");
if(rc&4) printf("1"); else printf("0");
if(rc&2) printf("1"); else printf("0");
if(rc&1) printf("1"); else printf("0");
printf(" %u %u\n",c,v);
}
}
printf("sub\n");
for(ra=0;ra<4;ra++)
{
for(rb=0;rb<4;rb++)
{
rd=(ra&1)+((~rb)&1)+1;
rc=ra+((~rb)&3)+1;
rd=(rd>>1)&1;
re=(rc>>2)&1;
if(re) c=0; else c=1;
if(rd!=re) v=1; else v=0;
if(ra&2) printf("1"); else printf("0");
if(ra&1) printf("1"); else printf("0");
printf(" - ");
if(rb&2) printf("1"); else printf("0");
if(rb&1) printf("1"); else printf("0");
printf(" = ");
if(rc&4) printf("1"); else printf("0");
if(rc&2) printf("1"); else printf("0");
if(rc&1) printf("1"); else printf("0");
printf(" %u %u\n",c,v);
}
}
Теперь ваш вопрос говорил о числах без знака, да? так что вы можете не заботиться ни о бите V, ни о правой половине, подписанной половине.
Вот немного HDL/RTL для небольшого 16-битного процессора, который я реализовал:
case 4b0000:
{
//0000 add rd,rs
op_a = bundle(1b0,reg[bundle(2b0,inst[4;8])].value);
op_b = bundle(1b0,reg[bundle(2b0,inst[4;4])].value);
op_res = op_a + op_b;
reg[1].value[CBIT] <= op_res[16];
reg[1].value[NBIT] <= op_res[15];
if(op_res[16;0] == 16h0000)
{
reg[1].value[ZBIT] <= 1b1;
}
else
{
reg[1].value[ZBIT] <= 1b0;
}
if((op_a[15] == op_b[15]) && (op_res[15] != op_b[15] ) )
{
reg[1].value[VBIT] <= 1b1;
}
else
{
reg[1].value[VBIT] <= 1b0;
}
reg[bundle(2b0,inst[4;8])].value <= op_res[16;0];
}
case 4b0001:
{
//0001 sub rd,rs
op_a = bundle(1b0,reg[bundle(2b0,inst[4;8])].value);
op_b = bundle(1b0,reg[bundle(2b0,inst[4;4])].value);
op_res = op_a - op_b;
reg[1].value[CBIT] <= (~op_res[16]);
reg[1].value[NBIT] <= op_res[15];
if(op_res[16;0] == 16h0000)
{
reg[1].value[ZBIT] <= 1b1;
}
else
{
reg[1].value[ZBIT] <= 1b0;
}
if((op_a[15] != op_b[15]) && (op_res[15] == op_b[15] ) )
{
reg[1].value[VBIT] <= 1b1;
}
else
{
reg[1].value[VBIT] <= 1b0;
}
reg[bundle(2b0,inst[4;8])].value <= op_res[16;0];
}
Я видел / видел msbit для подписанного переполнения в другой логике и не смог найти случая, когда он не соответствовал методу переноса и выполнения при попытке каждой возможной комбинации в прямом анализе.
Если я переборщил с ответом, я не против обрезать его в начале, где показано, что 5 - 0 имеет 1 как перенос из 1, что для вычитания не является переполнением. Длинный ответ, потому что может быть трудно разобраться со знаком и без знака и с тем, как сумматор работает в логике в целом. Сумматор не знает и не заботится о подписанном или беззнаковом, он заботится о сложении и вычитании, с вычитанием вы инвертируете второй операнд, инвертируете перенос в lsbit и перенос msbit (подумайте о добавлении, добавлении с переносом , саб и саб с переносом). Подписанный и неподписанный позаботится о себе (красота дополнения до двух). Сведение вышеизложенного к обсуждению только без знака делает его более чем наполовину простым, поскольку переполнение со знаком не (так) очевидно (как переполнение без знака) для случайного наблюдателя.
Я очень надеюсь, что я вырезал и вставил отлаженный HDL, получу много ответов/исправлений, если я этого не сделал... Я провел несколько дней, убеждая себя во всем вышеперечисленном и сравнивая с результатами других процессоров, к которым у меня был доступ, и т. д. Надеюсь, это сэкономит вам несколько дней.
person
old_timer
schedule
22.10.2011