Comments 15
Отличный результат. В части 3 я Вам написал в комментарии:
В РС пишется то, что и ранее. А вот наружу выдается pc_result и там защелкивается в буфере синхронной памяти. Так работает память. Для данных вы читаемые данные не получите в текущем такте, только в следующем. И нужен будет дополнительный порт записи в РОНы. Еще нужен будет bypass для загружаемых данных чтобы следующая команда не тормозила, если эти данные нужны ей.
И у Вас будет и синхронная стандартная память, и однотактная модель.
К моему удовольствию, Вы сделали то, о чем я Вас просил. Вам нужно только еще почитать как делать побайтовую запись в память и все будет отлично. Проблема чтения после записи Вами выдумана по незнанию как работает синхронная память. Команда записи может выполняться в том же такте , что и команды АЛУ. Результат АЛУ можно было и не передавать на следующую стадию, а писать сразу в РОН. А вот что Вы хорошо сделали, так это bypass данных команд LD.
В итоге у вас все та же однотактная модель ,но с синхронной памятью . И это уже здорово.
Кстати, именно поэтому Вы не потеряли на коремарке ничего. Ну только несколько сотен тактов на выдуманной (для данной модели !) проблеме чтения после записи.
Так это зависит от устройства памяти. Понятно, что с побайтовым доступом можно писать за один такт, но если подключат микросхему с 32 ножками данных, тогда вариантов не много, за один такт не получится.
always@(posedge clock) begin
old_data <= rom[d_addr[31:2]];
end
wire [31:0] new_data = {byte_mask[3] ? aligned_out[31:24] : old_data[31:24],
byte_mask[2] ? aligned_out[23:16] : old_data[23:16],
byte_mask[1] ? aligned_out[15:8] : old_data[15:8],
byte_mask[0] ? aligned_out[7:0] : old_data[7:0]};
always@(posedge clock) begin
if (old_data_w) begin
rom[old_addr[31:2]] <= new_data;
end
end
Кажется, я этот момент откладывал до появления кэша.
А вот заводить ещё один порт записи в регистры совсем не хотелось бы, сейчас модуль регистров занимает 36 ячеек логики, а так значения придётся комбинировать и 36 превратится в тысячу или две. Они-то появятся, если вектор ядер приделать, но это на будущее.
"Акулов не бывает". Там 4 банка по 8 будет. [31:0] это как из Харрисов идет так всех в заблужденье и вводит. Посмотрите ARM® Cortex®-M Processor based System Prototyping on FPGA , у них там есть утилитка fromelf которая бинарник бьет на банки. (Ее в доступе нет, но смысл понятен)
Я Харрисов не читал. Было в планах переделать на побайтовый доступ, когда буду кэш приделывать, для ООО кажется без него не обойтись. ARM'овское руководство что-то не ищется.
Я Харрисов не читал.
Значит у Вас талант к процессорам ибо Вы идеально точно повторили в первой части однотактную модель, приведенную в их книге.
Угу, когда писал, заметил, что там особо и отклониться некуда. И в этом смысле возникает вопрос, откуда у авторов VexRiscv, DarkRiscv, SERV и прочих такие гигантские частоты и такие маленькие размеры в LUT. Если частоту ещё можно объяснить быстрым ПЛИСом в идеальном варианте при 0 градусов и идеально нарезанным конвейером (пробовал тестово наставить промежуточных регистров), то количество LUT в таком случае выглядит совсем сказкой, ведь каждый промежуточный регистр надо умножать на 32. rs1, rs2, rd переносишь на следующий этап и уже +96 регистров.
Мне очень понравился цикл данных статей, спасибо за тем что поделились!
А зачем вы пишете "if (reset == 1)" а не просто "if(reset)"? Ну то есть я знаю такую школу мысли, но мне интересна ваша аргументация.
Подловили как новичка ) . Ещё можно bool++ делать и униформ инициализацию для указателя на функцию.
А я вот не понял ни вопроса Юрия , ни Вашего ответа. Вот если бы вопрос был в стиле книги Харрисов (еще раз спасибо DmitryZlobec) :"Какое несоответствие между рисунком паровозика и приложенной к нему модели ?" Такой вопрос был бы мне понятен.
В C++ код вида
if (a != b)
return true;
else
return false;
можно заменить на
return a != b;
потому что нет смысла писать
if (true)
return true;
else
return false;
Так больше новички пишут.
Я пишу if(nres==0) уже лет 25 и даже не задумываюсь, что это признак новичка :) Я просто на это не обращаю внимания. Вот если бы книга Харрисов уже тогда была мне доступна, то у меня вошло бы в привычку писать if(!nres)
Вы в своем коде напрочь игнорируете скобки, там где они и не нужны особо. Это явный признак профи (старичка). Я вот себе такого не позволяю и все беру в скобки, и потом пересчитываю чтобы открывающих было ровно столько сколько закрывающих
Процессор на коленке ч.4. Конвейер