Содержит примеры форматов команд, микрокода команд и т.п. для ARC - процессоров
Фрагменты:
За управление ветвлением отвечают следующие устройства процессора:
Устройство управления ветвлением (control branch logic) – на вход этого устройства поступает поле COND регистра микрокоманд (т.е. код конкретной команды ветвления), 13-й бит (бит непосредственной адресации) из регистра команд (IR), а также значение слова состояния (т.е. регистров флагов psr). На выходе этого устройства получаем 3 сигнала (в зависимости от выполнения условия и самого условия): next, jump, instruction decode.
Счётчик адреса микропрограммы (CSAI – control store address incrementer) – следующий адрес микрокода (т.е. текущий адрес микрокода +1). Входной информацией этого устройства является текущий адрес микропрограммы, выходной – инкрементированное значение входного значения.
Мультиплексор адреса микропрограммы (CS address MUX) – мультиплексор, который в зависимости от кода перехода (next, jump, instruction decode), полученного с устройства управления ветвлением, выбирает адрес, на который перейдет микропрограмма. Если на управляющий вход мультиплексора пришло значение next, то на выход подаётся значение адреса, которое получено счётчиком адреса микропрограммы. Если на управляющий вход пришло значение jump, то значение адреса берётся из поля JUMP ADDR регистра микрокоманд (MIR). Если на управляющий вход пришло значение instruction decode, то значение адреса получается путем добавления к коду команды (31, 30, 24-19 биты регистра команд) одного старшего бита, равного 1, и двух младших битов, равных 0.
Пример микрокода команды bneg
1) Формат команды:
bneg disp22 ; если слове состояния (регистре psr) бит n =1 (т.е. переход при отрицательном значении), то перейти по адресу = текущий адрес + disp22.
Код команды: op=00, op2=010, 000.
Адрес при декодировании: 10001000000=1024+64=1088.
2) Микрокод команды bneg:
0: IR=AND(PC, PC); MemRD.
//выполнение этой микрокоманды не связано с какой-то конкретной командой АЛУ, т.к. у нас выполняется операция чтения. Даже когда операция в АЛУ выполнится, то её результат не сохранится, т.к. мультиплексор C Bus из двух шин данных из памяти и из АЛУ выберет одну в зависимости от поля RD в регистре микрокоманд. В нашем случае, это будет шина данных из памяти, как раз она и сохранится в блоке регистров.
Посмотрите на схему процессора ARC. Проследите за значением поля RD из регистра микрокоманд (MIR). Оно управляет чтением из основной памяти, а также является сигналом выбора для мультиплексора C Bus (C Bus MUX).
Когда сигнал чтения выставлен, то адрес, по которому должно произойти чтение берётся с шины A. Но для этого на шине A должно появиться значение. Оно там появится, только если на информационные каналы мультиплексора A подать код регистра, из которого надо считать информацию.
Так для нашего случая, в регистре микрокоманд (MIR) в поле A нужно указать код регистра PC.
1: DECODE.
…
1088: JUMP 2.
//этот адрес одинаковый для всех команд ветвления
…
2: temp0=LSHIFT10(IR).
3: temp0=RSHIFT5(temp0).
4: temp0=RSHIFT5(temp0).
//выполнение действий со 2-ого адреса по 4-й дают следующее:
в регистре команд содержится 22 битное значение смещения адреса. Задача заключается в том, чтобы корректно переписать только это 22 битное значение в регистр (в нашем случае, это регистр temp0). Следует напомнить, что все регистры 32 битные. И в регистре команд помимо 22 битного значения смещения старшие 10 бит заняты кодами команды и др.
Для корректного извлечения значения смещения сначала в регистр temp0 записывается значение регистра команд (IR) смещенное на 10 разрядов влево. Это действие нужно для того, чтобы избавится от лишних 10 битов, которые также хранятся в регистре команд (это старшие 10 бит).
После этого регистр temp0 2 раза сдвигается вправо на 5 разрядов каждый раз (т.к. нет команды сдвига вправо на 10 разрядов). Это возвращает обратно веса разрядов, и в регистре temp0 хранится 22 битное значение из регистра команд. А старшие 10 бит регистра temp0 хранят нулевые значения.
5: IR=RSHIFT5(IR).
6: IR=RSHIFT5(IR).
7: IR=RSHIFT5(IR).
//выполнение действий с 5-ого адреса по 7-й дают возможность сдвинуть вправо на 15 разрядов регистр команд, получаем, что 28-й бит (старший бит поля cond регистра IR) становится 13-м. Следовательно, он влияет на устройство управления ветвлением (Control branch logic). [см. выше декодирование ветвления и поле cond]
8: JIMM 12; IR=ADD(IR, IR). //если бит непосредственного значения выставлен (т.е. равен 1), то это команда ветвления ba. Иначе, одна из 4-х (be, bcs, bneg, bvs).
9: JIMM 13; IR=ADD(IR, IR). //если бит непосредственного значения равен 1, то это одна из 3-х команд (bcs, bneg, bvs). Иначе, следует перейти на следующий адрес микрокода (10) и выполнить команду be. [см. выше декодирование ветвления и поле cond]
…
13: JIMM 16; IR=ADD(IR, IR). //если бит непосредственного значения равен 1, то это одна из 2-х команд bneg, bvs). Иначе, следует перейти на следующий адрес микрокода (14) и выполнить команду bcs. [см. выше декодирование ветвления и поле cond]
16: JIMM 19; IR=ADD(IR, IR). //если бит непосредственного значения равен 1, то это команда bvs. Иначе, следует перейти на следующий адрес микрокода (17) и выполнить команду bneg. [см. выше декодирование ветвления и поле cond]
17: JN 12.
18: JUMP 2047.
…
12: PC=ADD(PC, temp0); JUMP 0.
…
2047: PC=INC(PC); JUMP 0.
3) Заполнение полей регистра микрокоманд (MIR):
0: IR=AND(PC, PC); MemRD.
A=PC
B= PC
C=IR
//Это микрокоманда загружает в регистр IR команду из памяти программы по адресу равному значению регистра PC. PC и IR – эти регистры не доступны пользователю, поэтому их коды должны браться из регистра микрокоманд.
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=1
WR=0
ALU=AND
COND=NEXT
JUMP ADDR=*
1: DECODE.
A=0
B=0
C=0
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU=AND
COND=DECODE
JUMP ADDR=*
//В процессоре при исполнении команды DECODE блокируется запись в блок регистров, поэтому команда АЛУ не играет роли.
Или может происходить следующее: Rg0=and(Rg0, Rg0), т.е. фактически значение в регистре Rg0 не изменяется.
…
1088: JUMP 2.
A=0
B=0
C=0
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU=AND
COND=JUMP
JUMP ADDR=2
…
2: temp0=LSHIFT10(IR).
A=IR
B= *
C=temp0
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU= LSHIFT10
COND=NEXT
JUMP ADDR=*
3: temp0=RSHIFT5(temp0).
A= temp0
B= *
C= temp0
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU= RSHIFT5
COND=NEXT
JUMP ADDR=*
4: temp0=RSHIFT5(temp0).
A= temp0
B= *
C= temp0
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU= RSHIFT5
COND=NEXT
JUMP ADDR=*
5: IR=RSHIFT5(IR).
A= IR
B= *
C= IR
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU= RSHIFT5
COND=NEXT
JUMP ADDR=*
6: IR=RSHIFT5(IR).
A= IR
B= *
C= IR
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU= RSHIFT5
COND=NEXT
JUMP ADDR=*
7: IR=RSHIFT5(IR).
A= IR
B= *
C= IR
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU= RSHIFT5
COND=NEXT
JUMP ADDR=*
8: JIMM 12; IR=ADD(IR, IR).
A= IR
B= IR
C=IR
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU=ADD
COND=JIMM
//перейти по адресу(в микрокоде) в поле JUMP ADDR, если IR[13]=1.
JUMP ADDR=12
9: JIMM 13; IR=ADD(IR, IR).
A= IR
B= IR
C= IR
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU=ADD
COND=JIMM
JUMP ADDR=13
…
13: JIMM 16; IR=ADD(IR, IR).
A= IR
B= IR
C= IR
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU=ADD
COND=JIMM
JUMP ADDR=16
16: JIMM 19; IR=ADD(IR, IR).
A= IR
B= IR
C= IR
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU=ADD
COND=JIMM
JUMP ADDR=19
17: JN 12.
A=0
B=0
C=0
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU=AND
COND=JN
//перейти по адресу (в микрокоде) в поле JUMP ADDR, если флаг n=1.
JUMP ADDR=12
18: JUMP 2047.
A=0
B=0
C=0
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU=AND
COND=JUMP
//безусловный переход по адресу (в микрокоде) в поле JUMP ADDR
JUMP ADDR=2047
…
12: PC=ADD(PC, temp0); JUMP 0.
A=PC
B= temp0
C= PC
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU=ADD
COND=JUMP
JUMP ADDR=0
//т.к. команды ветвления (переходов) работают с адресами, то после их удачного выполнения не нужно переходить на адрес 2047 (где инкрементируется PC), т.к. его значение уже поменялось. Изменение PC – это цель успешного выполнения команд ветвления. Напомню, что PC будет показывать адрес следующей выполняемой команды. И не забудьте вернуться на нулевой адрес, т.к. выполнение программы должно продолжаться.
В данном случае, в микрокоде при переходе по адресу 12 будет успешное выполнение условия, а по адресу 2047 – нет (т.е. условие не верно).
…
2047: PC=INC(PC); JUMP 0.
A=PC
B= *
C= PC
AMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
BMUX=0 (код регистра-источника берётся из регистра микрокоманд (MIR))
CMUX=0 (код регистра-приёмника берётся из регистра микрокоманд (MIR))
RD=0
WR=0
ALU=INC
COND=JUMP
JUMP ADDR=0