Size: a a a

2020 October 28

V

Vadimatorik in Deus Volt!
spi - всегда комбинированный (через защелку)
источник

EF

Elvis Fox in Deus Volt!
Vadimatorik
Вот тоже думал. Что нет общего регистрового файла. Наружу только адрес записи/чтения и шина данных записи/чтения.
мне вот кажется что это оптимальное решение. Вместо адреса можно вывести флаги доступа к регистрам (valid или access, как у кого они называются)
источник

EF

Elvis Fox in Deus Volt!
А адрес декодировать уже снаружи
источник

V

Vadimatorik in Deus Volt!
Спасибо)
источник

EF

Elvis Fox in Deus Volt!
Elvis Fox
мне вот кажется что это оптимальное решение. Вместо адреса можно вывести флаги доступа к регистрам (valid или access, как у кого они называются)
Вот к примеру шина
wire             riscv_mem_valid;
wire             riscv_mem_ready;
wire [31:0]          riscv_mem_addr;
wire [31:0]          riscv_mem_wdata;
wire [3:0]          riscv_mem_wstrb;
wire [31:0]          riscv_mem_rdata;
.mem_valid         (riscv_mem_valid),    // out
.mem_ready         (riscv_mem_ready),    // in
.mem_addr          (riscv_mem_addr),    // out
.mem_wdata         (riscv_mem_wdata),    // out
.mem_wstrb         (riscv_mem_wstrb),    // out
.mem_rdata         (riscv_mem_rdata),    // in

wdata, wstrb (write strobe) идут на все блоки одновременно. valid декодируется в зависимости от адреса, и на каждый блок приходит свой valid. У блока может быть несколько входов valid, если там несколько независимых регистров, как у вас. Например cfg_valid, cnt_valid, err_valid, и т.д.
ready и rdata мультиплексируются в зависимости от того же адреса\
источник

EF

Elvis Fox in Deus Volt!
Мастером на шине будет SPI, я так понимаю
источник

EF

Elvis Fox in Deus Volt!
Elvis Fox
Вот к примеру шина
wire             riscv_mem_valid;
wire             riscv_mem_ready;
wire [31:0]          riscv_mem_addr;
wire [31:0]          riscv_mem_wdata;
wire [3:0]          riscv_mem_wstrb;
wire [31:0]          riscv_mem_rdata;
.mem_valid         (riscv_mem_valid),    // out
.mem_ready         (riscv_mem_ready),    // in
.mem_addr          (riscv_mem_addr),    // out
.mem_wdata         (riscv_mem_wdata),    // out
.mem_wstrb         (riscv_mem_wstrb),    // out
.mem_rdata         (riscv_mem_rdata),    // in

wdata, wstrb (write strobe) идут на все блоки одновременно. valid декодируется в зависимости от адреса, и на каждый блок приходит свой valid. У блока может быть несколько входов valid, если там несколько независимых регистров, как у вас. Например cfg_valid, cnt_valid, err_valid, и т.д.
ready и rdata мультиплексируются в зависимости от того же адреса\
И у меня есть блок io_map,
где происходит это декодирование / мультиплексирование адреса
типа такого
function void io_port(input [31:0] addr, output reg valid, input ready, input [31:0] rdata);
   begin
     casez({mem_valid, mem_addr})
       {1'b1, addr}:
       begin
         valid = 1'b1;
         mem_ready = ready;
         mem_rdata = rdata;
       end
       
       default:
         valid = 1'b0;
     endcase
   end
 endfunction

......
always_comb begin
// USB
   io_port(32'b0000_0000__0000_0000__0000_0001__????_????,   // 0x0000_0100..0x0000_01FF
               usb_io_valid,      usb_io_ready,       usb_io_rdata);

   // EPCQ flash memory cache
   io_port(32'b0000_0000__1???_????????_????????_??00,   // 0x0080_0000..0x00FF_FFFC
               epcq_cache_valid,    epcq_cache_ready,     epcq_cache_rdata);
end
источник

EF

Elvis Fox in Deus Volt!
немного покарежило код
источник

EF

Elvis Fox in Deus Volt!
Если это массив, то там будет некий массив сигналов valid
wire [15:0] pwm_cnt_valid_array = {16{pwm_cnt_valid}} & (16'd1 << addr[3:0]);
К примеру
далее эта шина подключается прямо к массиву инстансов PWM, и там автоматически происходит unpack по одной линии на каждый инстанс блока.
источник

EF

Elvis Fox in Deus Volt!
соответственно мастер (SPI?) выдает сигнал что хочет обратиться к каунтеру, и номер блока через адрес. Либо если всё делать по адресу, то можно другую часть шины адреса декодировать в pwm_cnt_valid, pwm_err_valid, etc...
источник

EF

Elvis Fox in Deus Volt!
а PWMы внутри себя независимо все делают напрямую со своими регистрами
источник

V

Vadimatorik in Deus Volt!
Elvis Fox
Мастером на шине будет SPI, я так понимаю
Да, все так.
источник

V

Vadimatorik in Deus Volt!
"Фига шо творит". Не видел в учебнике такой конструкции. На заметку. Читаю дальше.
источник

V

Vadimatorik in Deus Volt!
Elvis Fox
а PWMы внутри себя независимо все делают напрямую со своими регистрами
Так. Я прочитал и все же не понял. Для чего нужен valid? Что мешает получать адрес и сразу по нему подключаться к регистром конкретного PWM блока?
источник

EF

Elvis Fox in Deus Volt!
valid это тоже самое что read или access в данном случае. Это доступ на чтение. Тут есть разные подходы, некоторые делают read и write, которые взаимоисключаемые, либо делают access и write, где access==1 при любом доступе, а write==1 если это доступ на запись.
Можно и без него, по большому счету )
источник

EF

Elvis Fox in Deus Volt!
В большинстве случаев он используется как индикатор того, что адрес валиден.
источник

V

Vadimatorik in Deus Volt!
И еще не понял, откуда в io_port модуле возникла переменная mem_valid. Она глобальна что ли?
источник

EF

Elvis Fox in Deus Volt!
да, это порт в модуле. объявлен как reg, но поскольку он записывается блокирующем присвоением через  вызов функции из always_comb, то это комбинаторная логика.
источник

V

Vadimatorik in Deus Volt!
Elvis Fox
valid это тоже самое что read или access в данном случае. Это доступ на чтение. Тут есть разные подходы, некоторые делают read и write, которые взаимоисключаемые, либо делают access и write, где access==1 при любом доступе, а write==1 если это доступ на запись.
Можно и без него, по большому счету )
Ну для моего решения, да, полагаю. У меня всегда доступ за 1 такт по сути.
источник

V

Vadimatorik in Deus Volt!
И далее будет еще 1 вопрос. Вот я сделал их отдельно. 16 штук. Повесил все на шину. Написал декодер. А как их опросить? У меня такой вариант. Чтобы сделать единовременно это (опросить разом все 16 штук): сделать внутри каждого модуля дубликат регистров. в который попадают данные в случае, если общий для все модулей флаг установлен. Какой-нибудь "save_state".
источник