-
wowa
-
-
Не в сети
-
Давно я тут
-
-
Сообщений: 157
-
Спасибо получено: 37
-
-
-
-
|
От того и надо делать схемы синхронные - так чтобы дальнейшая обработка данных была уже после, ну или в любом случае между этими переходными процесами.. К сожалению именно этим ограничиватся скорость работы схем в ПЛИС.
|
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
|
-
kelmir
-
-
Не в сети
-
Новый участник
-
-
Сообщений: 7
-
Спасибо получено: 0
-
-
|
Объясните, пожалуйста, по поводу имени модуля. Правильно ли я понимаю, что оно уникально и константа при вызове в соответствии со стандартом? Если так, то как быть в ситуациях, когда нужно создать много однотипных модулей? Понимаю, что не критично, просто будет много похожих строк с разными именами, но хотелось бы задавать имя модуля в цикле, чтобы сократить код и улучшить читаемость.
|
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
|
-
leonem
-
-
Не в сети
-
Новый участник
-
-
Сообщений: 12
-
Спасибо получено: 0
-
-
|
В цикле вроде можно менять только нумерацию название останится прежним. Я писал так но я тоже пишу не давно.
|
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
|
-
leshabirukov
-
-
Не в сети
-
Захожу иногда
-
-
Сообщений: 56
-
Спасибо получено: 13
-
-
|
Можно сделать модуль - обёртку, принимающий числовой (статический) параметр, конкретная реализация выбирается в зависимости от значения параметра. Лучше такое писать на system verilog.
|
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
|
-
kelmir
-
-
Не в сети
-
Новый участник
-
-
Сообщений: 7
-
Спасибо получено: 0
-
-
|
Похоже, что можно с помощью именованного блока. В нем вызывать модуль сколько угодно раз под одним и тем же именем. Правда теперь не ясно с индексацией созданных модулей.
Вызвать то их вызвал, но если будет нужно в дальнейшем обратиться к ним, тогда проблема, т.к. у них одно имя. Примерчик с индексацией с этого же сайта:
.......
genvar index;
generate
for (index=0; index < 4; index=index+1)
begin: fu
func #(index) func_inst (
.fclk(clock),
.d( in ),
.q(o_q)
);
end
endgenerate
........
|
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
|
-
Серый Волк
-
-
Не в сети
-
Давно я тут
-
-
Сообщений: 82
-
Спасибо получено: 2
-
-
-
|
Не знаю какой пинок я получу - "волшебный" с полезной информацией или "напутственный" с пожеланиями... Однако задам вопрос здесь, дабы не заводить лишних тем.
Имею 27 двоичных разрядов. Столкнулся с необходимостью их декодировать до 8-ми 7-ми сегментных разрядов для индикаторов.
Посмотрел, существуют такие микрухи - преобразователи кодов, как 74185, однако как каскадировать их при такой толстой входной шине не представляю, поэтому графический метод был отметён в начале. Может подскажете или подтолкнёте в нужном направлении?
Спасибо.
"Холодает" - подумал Волк и натянул Красную Шапочку по самые уши...
|
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
|
-
alman
-
-
Не в сети
-
Завсегдатай
-
-
Сообщений: 263
-
Спасибо получено: 41
-
-
-
-
-
|
Серый Волк пишет: Имею 27 двоичных разрядов. Столкнулся с необходимостью их декодировать до 8-ми 7-ми сегментных разрядов для индикаторов.
Я "не настоящий сварщик, просто маску нашёл".
Вроде как 2^27 = 134 217 728 поэтому старшая единичка может и не поместиться в 8 разрядах.
А что если взять 8 делителей и 8 дешифраторов, соединив их таким образом, что частное от каждого делителя через дешифратор поступает на индикатор.
А остаток от деления на 10 одного деллителя идёт на вход следующего делителя.
Немного пошукал и нашёл две реализации деления // :Example:
//
// Simple divider.
// Based on :PH: Figure 4.36
module simple_divider(quotient,remainder,ready,dividend,divider,start,clk);
input [15:0] dividend,divider;
input start, clk;
output [15:0] quotient,remainder;
output ready;
// """"""""|
// 1011 | <---- dividend_copy
// -0011 | <---- divider_copy
// """"""""| 0 Difference is negative: copy dividend and put 0 in quotient.
// 1011 | <---- dividend_copy
// -0011 | <---- divider_copy
// """"""""| 00 Difference is negative: copy dividend and put 0 in quotient.
// 1011 | <---- dividend_copy
// -0011 | <---- divider_copy
// """"""""| 001 Difference is positive: use difference and put 1 in quotient.
// quotient (numbers above)
reg [15:0] quotient;
reg [31:0] dividend_copy, divider_copy, diff;
wire [15:0] remainder = dividend_copy[15:0];
reg [4:0] bit;
wire ready = !bit;
initial bit = 0;
always @( posedge clk )
if ( ready && start ) begin
bit = 16;
quotient = 0;
dividend_copy = {16'd0,dividend};
divider_copy = {1'b0,divider,15'd0};
end else begin
diff = dividend_copy - divider_copy;
quotient = { quotient[14:0], ~diff[31] };
divider_copy = { 1'b0, divider_copy[31:1] };
if ( !diff[31] ) dividend_copy = diff;
bit = bit - 1;
end
endmodule
и второй вариант
// Uses less register storage than simple divider.
module streamlined_divider(quotient,remainder,ready,dividend,divider,start,clk);
input [15:0] dividend,divider;
input start, clk;
output quotient,remainder;
output ready;
reg [31:0] qr;
reg [16:0] diff;
//
// 0000 1011
// """"""""|
// 1011 | 0001 0110 <- qr reg
// -0011 | -0011 <- divider (never changes)
// """"""""|
// 1011 | 0010 110o <- qr reg
// -0011 | -0011
// """"""""|
// 1011 | 0101 10oo <- qr reg
// -0011 | -0011
// """"""""| 0010 1000 <- qr reg before shift
// 0101 | 0101 0ooi <- after shift
// -0011 | -0011
// """"""""| 0010 ooii
// 10 |
//
// Quotient, 3 (0011); remainder 2 (10).
wire [15:0] remainder = qr[31:16];
wire [15:0] quotient = qr[15:0];
reg [4:0] bit;
wire ready = !bit;
initial bit = 0;
always @( posedge clk )
if ( ready && start ) begin
bit = 16;
qr = {16'd0,dividend};
end else begin
diff = qr[31:15] - {1'b0,divider};
if ( diff[16] )
qr = {qr[30:0],1'd0};
else
qr = {diff[15:0],qr[14:0],1'd1};
bit = bit - 1;
end
endmodule
Клоков это займёт немало, но в любом случае для глаза заметно не будет.
|
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
|
-
Alucard
-
-
Не в сети
-
Завсегдатай
-
-
Сообщений: 208
-
Спасибо получено: 20
-
-
-
-
|
Добрый день, уважаемые.
При проектировании DMA контроллера на ПЛИС пришел к выводу, что нужна некая архитектура подобная конечному автомату. Состояния:
- IDLE - DMA свободен
- SCAN - DMA обрабатывает поступивший запрос (возможно объединить с предыдущим)
- READ - Операция чтения данных в буфер.
- WRITE - Операция записи данных из буфера.
- RESET - Сброс
Насколько я понимаю, все действия должны происходить синхронно. Мои попытки сделать это на <a href="/index.php/verilog">verilog</a>: module DMA (
// inputs:
input wire clk,
input wire res, //Positive
input wire [15:0] a_address_reg,
input wire [2:0] a_device_reg, //Negative
input wire [15:0] b_address_reg,
input wire [2:0] b_device_reg, //Negative
input wire [15:0] count_reg,
inout reg [7:0] c_data,
output reg [15:0] c_address,
output reg c_we, //Negative
output reg c_oe, //Negative
inout reg [7:0] data,
output reg [15:0] address,
output reg we, //Negative
output reg oe, //Negative
output reg [2:0] device, //Negative
output reg busy //Negative
);
reg [3:0] state;
parameter idle = 0, scan = 1, read = 2, write = 3, reset = 4;
parameter lo = 0, hi = 1;
parameter clean = 65535;
always @(posedge clk or posedge res)
begin
if (res)
state = reset;
case(state)
idle:
begin
state <= scan; //Временная заглушка
busy <= hi;
end
scan:
begin
if ((a_address_reg == clean && b_address_reg == clean) || (a_device_reg == 1 && b_device_reg == 1))
state <= idle;
else
if (a_address_reg == clean)
state <= write;
else
state <= read;
end
read:
begin
state <= idle; //Временная заглушка
end
write:
begin
busy <= lo;
device <= a_device_reg;
address <= a_address_reg + c_address;
oe <= hi;
we <= lo;
c_oe <= lo;
c_we <= hi;
data <= c_data;
if (c_address < count_reg)
c_address <= c_address + 1;
else
state <= reset;
end
default:
begin
c_data <= 8'bZZZZZZZZ;
c_address <= lo;
c_we <= hi;
c_oe <= hi;
data <= 8'bZZZZZZZZ;
address <= lo;
we <= hi;
oe <= hi;
device <= 3'b111;
busy <= hi;
state <= idle;
end
endcase;
end
always @(state)
begin
end
endmoduleУ меня вопрос: правильно ли я все делаю? Меня интересует не алгоритм работы, а сами "блоки" состояний и их переходы. (структура case) Возможно, работа в состояниях должна происходить не в этом же always.
|
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Последнее редактирование: от Alucard.
|
-
Alucard
-
-
Не в сети
-
Завсегдатай
-
-
Сообщений: 208
-
Спасибо получено: 20
-
-
-
-
|
Совершенно случайно получился автомат: module DMA (
// inputs:
input wire clk,
input wire res, //Positive
input wire [15:0] a_address_reg,
input wire [2:0] a_device_reg, //Negative
input wire [15:0] b_address_reg,
input wire [2:0] b_device_reg, //Negative
input wire [15:0] count_reg,
inout reg [7:0] c_data,
output reg [15:0] c_address,
output reg c_we, //Negative
output reg c_oe, //Negative
inout reg [7:0] data,
output reg [15:0] address,
output reg we, //Negative
output reg oe, //Negative
output reg [2:0] device, //Negative
output reg busy, //Negative
output reg done
);
reg [3:0] state;
parameter reset = 0, set = 1, inc = 2;
parameter lo = 0, hi = 1;
parameter clean = 65535;
always @(negedge clk) //Переключение!
begin
case (state)
set:
state <= inc;
inc:
state <= set;
reset:
state <= set;
endcase
end
always @(negedge clk) //Операции
begin
case (state)
set:
data <= c_data;
reset:
begin
data <= 8'bZZZZZZZZ;
c_data <= 8'bZZZZZZZZ;
end
endcase
end
always @(posedge clk) //Операции
begin
case(state)
set:
begin
busy <= lo;
device <= b_device_reg;
address <= b_address_reg + c_address;
oe <= hi;
we <= lo;
c_oe <= lo;
c_we <= hi;
end
inc:
begin
if (c_address < count_reg)
c_address <= c_address + 1;
else
done <= hi;
end
reset:
begin
busy <= hi;
c_oe <= hi;
c_we <= hi;
c_address <= 0;
device <= 4'b1111;
oe <= hi;
we <= hi;
address <= 0;
done <= lo;
end
endcase;
end
always @(state)
begin
end
endmoduleОперации происходят по фронту тактовой частоты, а само переключение состояний по спаду тактовой. Компилятор сам обозвал такую конструкцию как State Machine.
|
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Последнее редактирование: от Alucard.
|
Время создания страницы: 0.140 секунд