Leo

Не Работает Сдвиговый Регистр В Верилог

145 сообщений в этой теме

Leo    3

Хотел спросить насчет сдвигового регистра я взял на сайте альтеры пример но он что то не заработал

www.altera.com/support/examples/verilog/verilog.html

www.altera.com/support/examples/verilog/ver-1x64-shift-reg.html

module shift_1x64 (clk,

shift,

sr_in,

sr_out,

);

input clk, shift;

input sr_in;

output sr_out;

reg [63:0] sr;

always@(posedge clk)

begin

if (shift == 1'b1)

begin

sr[63:1] <= sr[62:0];

sr[0] <= sr_in;

end

end

assign sr_out = sr[63];

endmodule

Тут есть какие то тонкости он не заполняет данными регистр и не передает данные на вывод и данные он должен выводить сразу как они обновились или в конце когда полностью заполнен регистр [63:0] sr;

Пример простой но почему то не работает. Хотя что то похожее видел в примерах у других.

Запускал с простым тест бэнчем данные приходят но в регистр не записываются.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vascom    647

Всё тут работает. Данные на выходе появятся после заполнения регистра sr[63:0].

Видишь это assign sr_out = sr[63]; - на выход идёт последний бит. А тут sr[0] <= sr_in; - заполнение регистра начинается с первого бита.

Покажи свой тестбенч, возможно в нём у тебя ошибка. Может ты клок не подал или shift не поставил в 1.

Изменено пользователем Vascom

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Leo    3

Привел всё сразу со всеми изменениями которые внес. Что не так не понятно.

module counter (

shift,

clk,

sr_in,

sr_out3

);

input shift,clk;

input wire [7:0]sr_in;

output [7:0] sr_out3;

reg [31:0]sr;

always @ (posedge clk)

begin

if (shift == 1'b1)

begin

sr[31:1] <= sr[30:0];

sr[0] <= sr_in;

$display("%d",sr[n]);

end

end

assign sr_out3 = sr[31];

initial

$monitor($stime,, shift,, clk,,, sr_out3, sr_in );

endmodule

module test_counter;

reg shift,clk;

reg [7:0]sr_in;

wire [7:0] df1,df4;

counter counter_inst(shift,clk,sr_in,

df1,df4);

always

#10 clk = ~clk;

initial

begin

clk = 0;

shift = 0;

sr_in=8'h00;

#10;

@(posedge clk)

#0

begin

shift = 1;

sr_in=8'h55;

end

@(posedge clk)

#0

begin

shift = 0;

sr_in=8'h00;

end

#10;

@(posedge clk)

#0

begin

shift = 1;

sr_in=8'h56;

end

@(posedge clk)

#0

begin

shift = 0;

sr_in=8'h00;

end

#10;

@(posedge clk)

#0

begin

shift = 1;

sr_in=8'h53;

end

@(posedge clk)

#0

begin

shift = 0;

sr_in=8'h00;

end

#10;

@(posedge clk)

#0

begin

shift = 1;

sr_in=8'h51;

end

@(posedge clk)

#0

begin

shift = 0;

sr_in=8'h00;

end

end

initial

begin

#200 $finish;

end

initial

begin

$dumpfile("out.vcd");

$dumpvars(0,test_counter);

end

endmodule

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vascom    647

Внеси это в тег "Код" пожалуйста.

Ну и сразу видны ошибки у тебя:

input wire [7:0]sr_in;
sr[0] <= sr_in;

Вход у тебя восьмибитный, но в регистр ты кладёшь только один бит, причём непонятно какой (нулевой наверное).

Изменено пользователем Vascom

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
UTSource

Найдите миллионы труднодоступных

электронных компонентов

Leo    3

Из этого я делаю вывод что sr[7] и смещение sr[31:1] <= sr[30:0]; тоже переделываю

if (shift == 1'b1)

begin

sr[31:1] <= sr[30:0];

sr[0] <= sr_in;

на

if (shift == 1'b1)

begin

sr[31:1] <= sr[23:0];

sr[7] <= sr_in;

Изменение есть но результата нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vascom    647

Должно быть

sr[31:8] <= sr[23:0];
sr[7:0] <= sr_in;

Разберись в понимании шин и битов.

И на выход у тебя идёт лишь один старший бит assign sr_out3 = sr[31];

Если ты хочешь все 8 бит на выходе иметь, то сделай

assign sr_out3 = sr[31:24];
Изменено пользователем Vascom

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Leo    3

Как хорошо не много просветлело и заработало. Но мне попался ещё один сдвиговый регистр этот заработал почти сразу

sr <= { sr[31:0],sr_in };

но не очень ясно если разница с предыдущим вариантом

sr[31:8] <= sr[23:0]; sr[7:0] <= sr_in;

или это разнообразие в написании. Ещё хотел спросить насчет For вроде он не используется в коде при описании для микросхемы а только в тест бэнче?

Изменено пользователем Leo

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vascom    647

Это разнообразие в описании.

Причём вариант

sr <= { sr[31:0],sr_in };

написан неграмотно. Слева у нас 32-рязрядный регистр sr, а справа ему присваивается уже 40-разрядное значение. Конечно компилятор умный, он отбросит старшие 8 разрядов, но вдруг нет? Так что если уж писать в одну строку, то так:

sr <= { sr[23:0],sr_in };

В общем все неочевидности лучше сразу убирать. Так код и читается лучше, и поддерживается и работает .

For вполне можно использовать и для описания микросхемы. Иногда это позволяет сделать код более компактным.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Leo    3

Я решил попробовать цикл For

module counter (

shift,

clk,

sr_in,

sr_out,

sr_out1,

sr_out2,

sr_out3,

sr_out4

);

input shift,clk;

input wire [7:0]sr_in;

output [7:0]sr_out,sr_out1,sr_out2,sr_out3,sr_out4;

reg [7:0] sr [31:0];

integer n;

always @ (posedge clk)

if (shift == 1'b1)

begin

for (n = 31; n>0; n = n-1)

begin

sr[n] <= sr[n-1];

$display("%d",sr[n]);

end

sr[0] <= sr_in;

end

assign sr_out = sr[7];

assign sr_out1 = sr[15];

assign sr_out2 = sr[23];

assign sr_out3 = sr[31];

initial

$monitor($stime,, shift,, clk,,,sr_out, sr_in );

endmodule

[code]

module shift_8x64_taps (clk,

shift,

sr_in,

sr_out,

sr_tap_one,

sr_tap_two,

sr_tap_three,

);

input clk, shift;

input [7:0] sr_in;

output [7:0] sr_tap_one, sr_tap_two, sr_tap_three, sr_out;

reg [7:0] sr [63:0];

integer n;

always@(posedge clk)

begin

if (shift == 1'b1)

begin

for (n = 63; n>0; n = n-1)

begin

sr[n] <= sr[n-1];

end

sr[0] <= sr_in;

end

end

assign sr_tap_one = sr[15];

assign sr_tap_two = sr[31];

assign sr_tap_three = sr[47];

assign sr_out = sr[63];

endmodule

Но проблема таже не загружаются данные хотя пример обсолютно такой же.Только значения поменял.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vascom    647

Ты упорно пытаешься выходным многоразрядным шинами присваивать однобитовые значения.

Строй эпюры всех сигналов, и у видишь где у тебя проблемы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Leo    3

При построении эпюр выходит что не загружается регистр.

sr[0] <= sr_in;

А изменить sr[0] на sr[7:0] не удается компилятор ругается. И

assign sr_out = sr[7]; 

на

assign sr_out = sr[7:0];

тоже.

Ведь при таком написании он заносит в регистр 8 бит.

Но проблема помойму в цикле For где n должно быть типа регистра я запутался.

Пример который я взял тоже работает с регистром а не содним сигналом?

И что значит построить все эпюры загрузка не идет и дальше нету результатов.

Изменено пользователем Leo

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vascom    647

Так sr_out у тебя же и есть 8 бит.

А вот за масситвы ты рано взялся. Это reg [7:0] sr [31:0]; тут совершенно ни к чему.

Ты всё слишком усложнил, не разобравшись с простейшим.

Выясняй почему регистр sr[0] не загружается. И не используй конструкции for без необходимости. Как видишь, это тут всё лишь усложняет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Leo    3

Можно не много пояснений простой сдвиговый регистр у меня получился который был в самом начале он заполняется и выводит результат который указан assign sr_out = sr[7:0]; через него проходят все предидущие и в конце в нем остается что

нужно sr[7:0]. Я взял не удачный пример но он приводился как продолжение сдвигового регистра разделяя его на части регистр

с отводами наверное для более правельного чтения куска регистра.Хотя что то не так. Я хотел на примере понять как работает цикл For.Так много операторов что не понятно какой правельно использовать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vascom    647

Хм, в Verilog совсем немного операторов. for работает так же как и везде.

А отвод из регистра сделать очень просто.

Допустим сдвиговый регистр наш по 8 бит сдвигает

sr[31:8] <= sr[23:0];
sr[7:0] <= sr_in;

Тогда отводы будут такими

assign ssr_out = sr[31:24];
assign ssr_out_1 = sr[23:16];
assign ssr_out_2 = sr[15:8];
assign ssr_out_3 = sr[7:0];

При этом все они должны быть объявлены как 8-битные. Для лучшего понимания, наглядности и однозначности лучше каждый отдельно описать, а не в одну строку:

output [7:0] sr_out;
output [7:0] sr_out1;
output [7:0] sr_out2;
output [7:0] sr_out3;

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Leo    3

Я в коде цикла For удалил массив. Симулятор показывает что регистр заполняется побитно приходящими данными но только первые 8 бит а в эпюрах регистр так и не заполняется.Он не правельно читает sr_in врядли наверное проблема sr[n] <= sr[n-1];

он же отвечает за заполнение?

reg [31:0]sr;
integer n;
always @ (posedge clk)

if (shift == 1'b1)
	 begin

for (n = 31; n>0; n = n-1)
begin

sr[n] <= sr[n-1];

$display("%d",sr[n]);
end
sr[7:0] <= sr_in;
end
			 assign sr_out = sr[7:0];
			 assign sr_out1 = sr[15:8];
			 assign sr_out2 = sr[23:16];
			 assign sr_out3 = sr[31:24];

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vascom    647

Конечно. Раз у тебя 8 бит на входе, то и регистр надо заполнять по 8 бит, а не по одному биту. Переделай.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Leo    3

Не знаю как переделать цикл For вместо

sr[n] <= sr[n-1];

подставил

sr[31:8] <= sr[23:0];

но For тогда зачем как должно быть правельно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vascom    647

Вот так:

for (n = 1; n<4; n = n+1)
begin																										
  sr[(n+1)*8-1:n*8] <= sr[n*8-1:(n-1)*8];														
end
sr[7:0] <= sr_in;

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Leo    3

Вот это конструкция "больше вопросов чем ответов" Что то в твоей конструкции ему не понравилось и отладчик ругается.

reg [31:0]sr;
integer n;
always @ (posedge clk)
if (shift == 1'b1)
			 begin
for (n = 1; n<4; n = n+1)
begin
sr[(n+1)*8-1:n*8] <= sr[n*8-1:(n-1)*8]; 
$display("%d",sr[n]);
end
sr[7:0] <= sr_in;
end
							 assign sr_out = sr[7:0];
							 assign sr_out1 = sr[15:8];
							 assign sr_out2 = sr[23:16];
							 assign sr_out3 = sr[31:24];

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vascom    647

Ну а где ругань-то? И неправильно ты выводишь $display("%d",sr[n]);

Покажи что он пишет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Leo    3

ppp2.v:35: error: Part select expressions must be constant.

ppp2.v:35: : This lsb expression violates the rule: (n)*('sd8)

ppp2.v:35: error: Part select expressions must be constant.

ppp2.v:35: : This msb expression violates the rule: (((n)+('sd1))*('sd8))-('sd1)

ppp2.v:35: error: Part select expressions must be constant.

ppp2.v:35: : This lsb expression violates the rule: ((n)-('sd1))*('sd8)

ppp2.v:35: error: Part select expressions must be constant.

ppp2.v:35: : This msb expression violates the rule: ((n)*('sd8))-('sd1)

ppp2.v:35: error: Part select expressions must be constant.

ppp2.v:35: : This lsb expression violates the rule: ((n)-('sd1))*('sd8)

ppp2.v:35: error: Part select expressions must be constant.

ppp2.v:35: : This msb expression violates the rule: ((n)*('sd8))-('sd1)

6 error(s) during elaboration.

А как правельно?

$display("%d",sr[n]);

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vascom    647

ОК, значит нельзя такое через цикл for провернуть.

Забил бы ты на эти циклы. Это же не Си, а Верилог, тут и без циклов всё отлично и понятно делается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Leo    3

Логично просто хотел понять что за код для работы с регистрами через For на сайте Альтера и при этом оказался не рабочий ведь заполнения регистра у меня тоже не получалось а оказалось всё просто. Есть ещё вопрос когда регистров много. С начала я заполняю один большой регистр разбиваю на меньшие а потом мне их надо сравнить все с определенными данными все сравнения пишутся в ручную для каждого малого регистра или они выводятся на оператор case.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vascom    647

Не совсем понятна твоя формулировка.

Если хочешь, чтобы они одновременно сравнивались - то конечно каждый описываешь.

А если хочешь по очереди - можешь через оператор case.

Ты пойми тут главное отличие от обычного программирования в широком параллелизме. То есть множество действий может быть выполнено одновременно за один такт. А не как в процессоре всё последовательно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Leo    3

О да меня параллелизм интересует почему и пробую понять. Просто когда их много штук 80 каждому пишется вывод assign sr_out = sr[7:0]; и для каждого пишутся сравнения которые нужны или в цикле возможно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Похожие публикации

    • Автор: Scinar
      Привет всем. Хочу собрать калькулятор на atmega 328p. Но не как не могу запустить LCD TIC55, основанный на сдвиговом регистре с чипом ML1001. Никогда не связывался с подобным дисплеем. Понравился очень экономичным потреблением тока и экономным количеством выводов управления - всего 3. Проблема в тактирование, как написать программу для вывода хотя б одного символа, документации мало нашел, так же есть библиотека для atmel studio 5, сам пользуюсь 7. Библиотку переделал под 7 но дисплей так ничего и не вывел. Подскажите как правильно написать программу, язык значения не имеет хоть assembler или С. Мне надо что б дисплей вывел хоть один символ корректно, дальше разберусь


      TIC55 Display Module.pdf
    • Автор: Корлет
      Надо составить схему регистра на триггерах, выполняющую сложение по модулю два. Складывается два двоичных числа: то, которое хранится на триггере, и то, которое подаётся на вход. С конъюнкцией получилось легко, а вот xor никак не могу придумать. Если кто знает, дайте, пожалуйста, схему или хотя бы расскажите на словах, что где.

    • Автор: admin
      Показано управление сдвиговым регистром 74HC164 в симуляторе Proteus. На основе этой схемы собраны бегущие огоньки из 16 светодиодов. 
      Бегущие огни.rar
    • Автор: Дмитрий Т87
      Здравствуйте. Прошу помощи в теме статитическая индикация 6 разрядного 7ми сегментного индикатора по 2м проводам Data и Clock.
      Есть такой код для 3х разрядного индикатора в CVavr Си
      Хочу закидывать данные в каждый разряд отдельно, и выводить эти функции в прерываниях avr микроконтроллера.

      // cd4094 control example by kalobyte.com 2009 #include <avr/io.h> #define F_CPU 1000000UL #include <util/delay.h> #define REG_PORT PORTB #define REG_DDR DDRB #define REG_PIN_DATA 3 #define REG_PIN_CLK 4 //--- #define REG_DATA_ON REG_PORT|=1<<REG_PIN_DATA; #define REG_DATA_OFF REG_PORT&=~(1<<REG_PIN_DATA); #define REG_CLK {REG_PORT|=1<<REG_PIN_CLK;REG_PORT&=~(1<<REG_PIN_CLK);} unsigned char digs[10]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; // katode // unsigned char digs[10]={0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; //anode void cd4094_init(void){ char i=0; while(i!=24){ REG_CLK i++; } } void cd4094(int dig){ char i,tmp,j; //dig = 123; int div[4]; div[1] = digs[dig%10]; dig = dig/10; div[2] = digs[dig%10]; div[3] = digs[dig/10]; for(j=3;j>0;j--){ tmp = div[j]; for(i=8;i>0;i--){ if(tmp & 0x80){ REG_DATA_ON } else {REG_DATA_OFF} tmp <<=1; REG_CLK } } } int main(void){ int i=1; REG_DDR = (1<<REG_PIN_DATA)|(1<<REG_PIN_CLK); REG_PORT = (0<<REG_PIN_DATA)|(0<<REG_PIN_CLK); cd4094_init(); //cd4094(2); while(i<999){ _delay_ms(1000); cd4094(i); i++; } return 0; }
      Вот такая схема

    • Автор: peanutwolf
      Добрый день!
      Прошу помощи.
      Имеется клемма, на вход которой поочередно необходимо подавать 12В. Подскажите, как это сделать с использованием сдвигового регистра.
      Пробовал делать через транзисторный ключ, но у меня его ни как не получается запереть при подаче 5 вольт на базу.
      Здесь я подаю 0 на базу, на коллекторе 12В:

      Здесь я подаю 1 на базу, напряжение на коллекторе так же 12В:

      Буду так же очень благодарен, если кто нибудь подскажет вариант решения без использования транзистора.
  • Сообщения

    • Череповато вздутием при меньшей температуре. А меньше ли у них ESR по сравнению со старыми, когда они были новыми? И есть ли запас по напряжению хотя бы в 1,5 раза больше максимального рабочего?
    • Посмотрели!? Убедились что ремонт девайса не Вашей области компетенции?!! (Ваш вопрос "зачем столько обмоток на трасформаторе?" это подтверждает) Для разовой работы лучше отдать девайс, пока не поздно (пока ещё недорого и довольно недолго (скорее всего сработала ещё одна защита)), сведущему специалисту (вернуть хозяину, пусть он ищет). Если есть перспектива пересесть за ремонт бесперебойников (хороший дополнительный кусок хлеба с маслом и икоркой) - расширить  свою компетенцию  до возможности ремонта ИБП (понадобится довольно много теории, практики, и обязательно "потренироваться на кошечках" (не все "кошечки выживут", поскольку понадобится довольно специфичная элементная база), и некоторое дополнительное оборудование (хороший осциллограф - обязателен!!)).   Кроме как послушать как гудит, какие ещё измерения проводили, чем и где?   И таки да. Девайс довольно китайский, могут быть неприятные сюрпризы...   С уважением, Сергей  
    • Вот ведь правильно сказал @солар , злые вы! Ну ведь понятно же из описания, что плата целая, трансформатор гудит, релюшки щелкают, а вот Вывод: сгорели индикаторы! А вы ему фото какой то деталюшки подсовываете. Хотя сам  @солар фото и подсунул    Дополнительное предложение по подразделам:  "Чем копать?",  "Как копать?",  "Что должно быть на столе во время копания?". А так же информационные разделы: "Влияние фазы Луны на ремонт" и "Применение карт Таро при диагностике".  
    • Может быть и на оборот, в протеусе все работает отлично а в железе нет! Так что отлаживать нужно не где удобнее, а там где есть 100% результат! А он может быть только в железе.
    •   Обрати внимание на нюансик - ты борешься за чистоту дифов, а у тебя 3 пары IRF-ов с довольно-таки тяжёлыми гейтами руляться КУН-ом с нищим током для этого; из-за чего и скорость ни в изду, и соответственно ИПХ ...авно. Дифы, какими бы они ни были шустрыми, никогда не исправят то, что исправить уже невозможно. 
    • не вводи его в заблуждение - ЭТА виновата:   там их на фото - тьма ...
    • А что это за деталька?   Смотрю и ....  или только я не вижу?