Добро пожаловать, Гость
Логин: Пароль: Запомнить меня

ТЕМА:

Re: Вопросы по языку Verilog 11 года 11 мес. назад #2769

От того и надо делать схемы синхронные - так чтобы дальнейшая обработка данных была уже после, ну или в любом случае между этими переходными процесами.. К сожалению именно этим ограничиватся скорость работы схем в ПЛИС.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Re: Вопросы по языку Verilog 11 года 11 мес. назад #2781

Объясните, пожалуйста, по поводу имени модуля. Правильно ли я понимаю, что оно уникально и константа при вызове в соответствии со стандартом? Если так, то как быть в ситуациях, когда нужно создать много однотипных модулей? Понимаю, что не критично, просто будет много похожих строк с разными именами, но хотелось бы задавать имя модуля в цикле, чтобы сократить код и улучшить читаемость.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Re: Вопросы по языку Verilog 11 года 11 мес. назад #2784

В цикле вроде можно менять только нумерацию название останится прежним. Я писал так но я тоже пишу не давно.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Re: Вопросы по языку Verilog 11 года 11 мес. назад #2800

Можно сделать модуль - обёртку, принимающий числовой (статический) параметр, конкретная реализация выбирается в зависимости от значения параметра. Лучше такое писать на system verilog.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Re: Вопросы по языку Verilog 11 года 11 мес. назад #2803

Похоже, что можно с помощью именованного блока. В нем вызывать модуль сколько угодно раз под одним и тем же именем. Правда теперь не ясно с индексацией созданных модулей.
Вызвать то их вызвал, но если будет нужно в дальнейшем обратиться к ним, тогда проблема, т.к. у них одно имя. Примерчик с индексацией с этого же сайта:
.......
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
........

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Re: Вопросы по языку Verilog 11 года 11 мес. назад #2804

А, модули полностью идентичные? Ну тогда вот вам пример, смотрите вызов Cell_Compare:
opencores.org/websvn,filedetails?repname...in%2Fstack_sorter.sv
Правда это system verilog.
Спасибо сказали: kelmir

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Re: Вопросы по языку Verilog 11 года 10 мес. назад #2831

Не знаю какой пинок я получу - "волшебный" с полезной информацией или "напутственный" с пожеланиями... Однако задам вопрос здесь, дабы не заводить лишних тем.
Имею 27 двоичных разрядов. Столкнулся с необходимостью их декодировать до 8-ми 7-ми сегментных разрядов для индикаторов.
Посмотрел, существуют такие микрухи - преобразователи кодов, как 74185, однако как каскадировать их при такой толстой входной шине не представляю, поэтому графический метод был отметён в начале. Может подскажете или подтолкнёте в нужном направлении?
Спасибо.
"Холодает" - подумал Волк и натянул Красную Шапочку по самые уши...

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Re: Вопросы по языку Verilog 11 года 10 мес. назад #2832

Серый Волк пишет: Имею 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

Клоков это займёт немало, но в любом случае для глаза заметно не будет.
Спасибо сказали: Серый Волк

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Re: Вопросы по языку Verilog 11 года 9 мес. назад #2841

Добрый день, уважаемые.
При проектировании DMA контроллера на ПЛИС пришел к выводу, что нужна некая архитектура подобная конечному автомату. Состояния:
  1. IDLE - DMA свободен
  2. SCAN - DMA обрабатывает поступивший запрос (возможно объединить с предыдущим)
  3. READ - Операция чтения данных в буфер.
  4. WRITE - Операция записи данных из буфера.
  5. 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.

Re: Вопросы по языку Verilog 11 года 9 мес. назад #2843

Совершенно случайно получился автомат:
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 секунд
Работает на Kunena форум