Nếu đây là lần đầu tiên đến với Điện Tử Việt Nam, bạn có thể đọc phần Hỏi đáp bằng cách nhấn vào liên kết. Có thể bạn cần đăng kí trước khi có thể gửi bài . Để bắt đầu xem bài viết, chọn diễn đàn bạn muốn thăm dưới đây.
mọi người ơi,giúp em với:em viết chương trình VHDL về bộ đếm timer.bộ đếm timer em đang viết có 4 đầu vào :clk,start,stop,reset.bộ đếm của em đếm từ 0-9:59.mong mọi người chỉ giúp!!!
em viết chương trình thế này nhưng ko biết viết về stop như thế nào.mọi người xem va chi giúp:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity seven_segdisplay is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
start : in STD_LOGIC;
stop : in STD_LOGIC;
digits1 : out STD_LOGIC_VECTOR (6 downto 0);
digits2 : out STD_LOGIC_VECTOR (6 downto 0);
digitm : out STD_LOGIC_VECTOR (6 downto 0));
end seven_segdisplay;
architecture Behavioral of seven_segdisplay is
begin
counter: process(clk,rst)
variable temp1 : integer range 0 to 10;
variable temp2 : integer range 0 to 10;
variable temp : integer range 0 to 10;
begin
if (start ='1') then
if (rst='1') then temp1 :=0;
temp2 :=0;
temp :=0;
ELSIF (clk'EVENT AND clk='1') THEN
temp1 := temp1 + 1;
if (temp1=10) then
temp1 := 0;
temp2 := temp2 + 1;
if (temp2=6) then
temp2 := 0;
temp := temp + 1;
if (temp = 10) then
temp :=0;
end if;
end if;
end if;
end if;
end if;
------ BCD to SSD conversion: --------
CASE temp1 IS
WHEN 0 => digits1 <= "1111110"; --7E
WHEN 1 => digits1 <= "0110000"; --30
WHEN 2 => digits1 <= "1101101"; --6D
WHEN 3 => digits1 <= "1111001"; --79
WHEN 4 => digits1 <= "0110011"; --33
WHEN 5 => digits1 <= "1011011"; --5B
WHEN 6 => digits1 <= "1011111"; --5F
WHEN 7 => digits1 <= "1110000"; --70
WHEN 8 => digits1 <= "1111111"; --7F
WHEN 9 => digits1 <= "1111011"; --7B
WHEN OTHERS => NULL;
END CASE;
CASE temp2 IS
WHEN 0 => digits2 <= "1111110"; --7E
WHEN 1 => digits2 <= "0110000"; --30
WHEN 2 => digits2 <= "1101101"; --6D
WHEN 3 => digits2 <= "1111001"; --79
WHEN 4 => digits2 <= "0110011"; --33
WHEN 5 => digits2 <= "1011011"; --5B
WHEN 6 => digits2 <= "1011111"; --5F
WHEN 7 => digits2 <= "1110000"; --70
WHEN 8 => digits2 <= "1111111"; --7F
WHEN 9 => digits2 <= "1111011"; --7B
WHEN OTHERS => NULL;
end case;
CASE temp IS
WHEN 0 => digitm <= "1111110"; --7E
WHEN 1 => digitm <= "0110000"; --30
WHEN 2 => digitm <= "1101101"; --6D
WHEN 3 => digitm <= "1111001"; --79
WHEN 4 => digitm <= "0110011"; --33
WHEN 5 => digitm <= "1011011"; --5B
WHEN 6 => digitm <= "1011111"; --5F
WHEN 7 => digitm <= "1110000"; --70
WHEN 8 => digitm <= "1111111"; --7F
WHEN 9 => digitm <= "1111011"; --7B
WHEN OTHERS => NULL;
END CASE;
END PROCESS counter;
Bạn nên nói ý tưởng của bạn là stop thế nào.Nếu stop cái tất cả về 0 và khi có start thì đếm lại từ đầu thì đơn giản rồi.nếu có stop tất cả ngừng đếm nhưng giữ nguyên trạng thái đầu ra và chờ khi có start thì đếm tiếp thì cũng ko khó.mình sẽ nói về trường hợp thứ 2 Vì bạn cho start như là một switch bằng lệnh IF và ý tưởng của bạn là nếu start = 1 thì thực hiện các lệnh sau "then" nhưng mình hỏi bạn rằng khi start = 0 thì sẽ như thế nào?Khi start = 0 thì tất cả cái lệnh sau "IF start = 1 then" sẽ không thực hiện nữa (trường hợp này ko có yêu cầu gì cho FPGA thực hiện tương đương với 1 thanh ghi nhớ trạng thái) như vậy đầu ra sẽ giữ nguyên trạng thái như trước khi có start = 0.Vậy không cần phải tạo thêm đầu vào stop làm gì nữa.mà ở đây có thể hiểu là khi start = 1 thì đếm còn khi start = 0 thì ngừng đếm và chỉ đếm tiếp khi nào có start=1.
Trong lập trình người ta thường sử dụng các tín hiệu điều khiển đó là clk, reset,CE(chip enable),stop/start(chung 1 đầu vào để tiết kiệm trạng thái) và một số điều khiển khác ứng dụng riêng. Với start/stop thì có thể tương đương với 2 trạng thái 1 hoặc 0 ứng với 2 mức logic cao hoặc thấp, hay có thể điều khiển start/stop bằng sườn lên xung lần 1 và sườn lên xung lần thứ 2.
Bạn thử nghĩ xem liệu có hợp lý không?đặc biệt là khi 2 trạng thái trong 3 trạng thái đó là stop và start.thường thì ko start thì stop và ko stop thì start. tuy nhiên ko phải ko có cách giải quyết.lập trình đầu vào sử dụng phím bấm (ấn thì mức logic cao tương đương là 1 và ko ấn thì là mức logic thấp tương đương 0).ấn lần nhất stop,ấn lần 2 start và giữ ấn thì reset về 0 (lập trình với thời gian ấn đủ lớn để ko nhầm với 2 trạng thái kia).tuy nhiên làm kiểu này ko ổn lắm vì độ trễ ấn là rất khó đoán biết được.trong VHDL có lệnh để kiểm tra sườn lên,sườn xuống và kiểm tra mức logic ('last value).Nếu chờ thời gian nữa mình sẽ gửi cho bạn code để giải quyết vấn đề trên nhưng dạo này mình bận quá nên chỉ nói ý tưởng cho bạn vậy.bạn đang học lớp nào bên MTA?
Hi hai_mta,
Đọc code của bạn có một số điểm cần lưu ý:
1) Reset
- Trước khi code VHDL/Verilog bạn nên học kĩ phần thiết kế số (digital design). Bạn nên vẽ được mạch trước khi viết code.
Trong VHDL, nếu muốn mô phỏng 1 flip-flop có chân reset là Asynchronous, bạn phải tuân theo code mẫu (template) như sau:
process(clk,rst)
begin
if(rst='1') then
Q <= '0';
elsif(rising_edge(clk)) then
Q <= D;
end if;
end process
Code này của bạn không đúng (hoặc không được khuyến khích)
if (start ='1') then
if (rst='1') then temp1 :=0;
temp2 :=0;
temp :=0;
ELSIF (clk'EVENT AND clk='1') THEN
Nếu bạn muốn mạch của bạn chạy với 1 tín hiệu start, thì tín hiệu start chẳng qua là CLOCK_ENABLE của Flip-Flop (nếu bạn chưa biết Flip-flop thường có những chân gì thì bạn tra cứu lại trong sách hoặc google)
signal Q: std_logic;
process(clk,rst)
begin
if(rst='1') then
Q <= '0';
elsif(rising_edge(clk)) then
if(start) then
Q <= D;
end if;
end if;
end process
2) Sử dụng variable
Variable thường được sử dụng như 1 dây (wire). Trong code này bạn sử dụng các variable như các register.
Code của bạn có thể không sai nhưng "ngộ" hoặc "lạ"
Nếu bạn muốn tạo các thanh ghi, hay registers để đếm thì nên dùng signal.
VHDL/Verilog không phải là ngôn ngữ lập trình.
Bạn nên hình dung/vẽ ra sơ đồ mạch bạn đang thiết kế trước khi viết code.
- Viết yêu cầu:
Các input: rst, clk, start, clr
Các output: Digit0, 1, ...
Rst: Asynchronous reset, khi rst = 1, trả các tín hiệu về 0
start: Chạy timer, start = 1 chay, start = 0 giữ nguyên
clear: trả các thanh ghi về giá trị 0. Khi clear = 1, không quan tâm giá trị của start, trả tất cả các biến về 0.
digit0, 1, ... sẽ được chuyển từ binary sang BCD. (BCD encoder)
Các tín hiệu nội bộ (internal)
thanh ghi: counter0, counter1, counter2 ...
thanh ghi counter0: trong điều kiện "chạy", counter0 sẽ đếm từ 0 tới 9, khi tới 9 thì quay lại 0
Sau đó sẽ code. Bạn chưa quen thì lấy giấy viết ra vẽ sơ đồ mạch.
signal counter0: std_logic_vector(3 downto 0);
process(clk,rst)
begin
if(rst='1') then counter0 <= 0;
elsif(rising_edge(clk)) then
if(clear='1') then --truong hop clear
counter0 <= 0;
else
if(start = '1') then --trường hợp chạy
if(counter0 = 9) then counter0 <= 0; else counter 0 <= counter 0+1; end if
end if;
end if;
....
end process
Bạn thử nghĩ xem liệu có hợp lý không?đặc biệt là khi 2 trạng thái trong 3 trạng thái đó là stop và start.thường thì ko start thì stop và ko stop thì start. tuy nhiên ko phải ko có cách giải quyết.lập trình đầu vào sử dụng phím bấm (ấn thì mức logic cao tương đương là 1 và ko ấn thì là mức logic thấp tương đương 0).ấn lần nhất stop,ấn lần 2 start và giữ ấn thì reset về 0 (lập trình với thời gian ấn đủ lớn để ko nhầm với 2 trạng thái kia).tuy nhiên làm kiểu này ko ổn lắm vì độ trễ ấn là rất khó đoán biết được.trong VHDL có lệnh để kiểm tra sườn lên,sườn xuống và kiểm tra mức logic ('last value).Nếu chờ thời gian nữa mình sẽ gửi cho bạn code để giải quyết vấn đề trên nhưng dạo này mình bận quá nên chỉ nói ý tưởng cho bạn vậy.bạn đang học lớp nào bên MTA?
Nhưng minh đọc sách có một bài tập như thế,mình đang học lớp ĐK6 (dân sự)
Hi hai_mta,
Đọc code của bạn có một số điểm cần lưu ý:
1) Reset
- Trước khi code VHDL/Verilog bạn nên học kĩ phần thiết kế số (digital design). Bạn nên vẽ được mạch trước khi viết code.
Trong VHDL, nếu muốn mô phỏng 1 flip-flop có chân reset là Asynchronous, bạn phải tuân theo code mẫu (template) như sau:
Code này của bạn không đúng (hoặc không được khuyến khích)
Nếu bạn muốn mạch của bạn chạy với 1 tín hiệu start, thì tín hiệu start chẳng qua là CLOCK_ENABLE của Flip-Flop (nếu bạn chưa biết Flip-flop thường có những chân gì thì bạn tra cứu lại trong sách hoặc google)
2) Sử dụng variable
Variable thường được sử dụng như 1 dây (wire). Trong code này bạn sử dụng các variable như các register.
Code của bạn có thể không sai nhưng "ngộ" hoặc "lạ"
Nếu bạn muốn tạo các thanh ghi, hay registers để đếm thì nên dùng signal.
VHDL/Verilog không phải là ngôn ngữ lập trình.
Bạn nên hình dung/vẽ ra sơ đồ mạch bạn đang thiết kế trước khi viết code.
Em ko đồng ý với jefflieu ở điểm anh cho rằng variable sử dụng như 1 dây.mà signal sử dụng như 1 wire mới đúng. Và đúng là VHDL ko phải là ngôn ngữ lập trình mà là ngôn ngữ mô phỏng thôi tuy nhiên ko phải là với bất kỳ bài toán nào cũng hình dung cho được "vẽ ra sơ đồ mạch" trước khi viết code mà theo em nên hình dung được entity và những vấn đề giải quyết trong entity đó là gì.vì với những bài toán lớn thì ko thể làm như vậy được.
Và đúng là VHDL ko phải là ngôn ngữ lập trình mà là ngôn ngữ mô phỏng thôi tuy nhiên ko phải là với bất kỳ bài toán nào cũng hình dung cho được "vẽ ra sơ đồ mạch" trước khi viết code mà theo em nên hình dung được entity và những vấn đề giải quyết trong entity đó là gì.vì với những bài toán lớn thì ko thể làm như vậy được.
- Với VHDL/Verilog, chỉ cần hình dung được mạch ở mức RTL như mình đã vẽ ... không cần hình dung ở mức thấp hơn nữa. Dù bài toán lớn cỡ nào ... ở mức cuối cùng có thể tiến hành coding bằng VHDL/Verilog thì ở RTL, vẫn chỉ quanh quẩn Register, Multiplexer, ... và các hàm logic. Cái lợi của "Behavioral" modeling là có thể mô tả "hành vi" của mạch ... sau đó công cụ sẽ synthesize ra mạch cho bạn, thay vì bạn phải design theo kiệu "structure" modeling" ... nhưng khi bạn code "behavioral" bạn cũng sẽ hình dung được mạch sẽ được tổng hợp ra thế nào, dĩ nhiện là không chi tiết đến mức AND-OR ... nếu chi tiết đến mức logic AND-OR thì behavioral modeling ko còn lợi thế nữa.
Thực ra, lỗi của hãng đó ( gọi là hãng vì không chỉ một model sản phẩm) là về phần cứng, ĐT tuy không biết về lập trình phần mềm nhưng cũng thấy rằng sẽ chẳng khó khăn gì đáng...
Đúng, nếu chú tâm thì chỉ cần mỗi tiếng Việt là đã khá đủ để làm đa số công việc thông thường, ở thời đại ngày nay khi tài liệu sách vở phương tiện thông tin liên lạc đã nhiều. Nhưng cũng chính ở thời nay giao lưu các nước nhiều...
Dạ cháu nghĩ chú dinh... cứ mạnh dạn gửi thư đi ạ, chú có thể gửi bằng văn bản in chuyển phát nhanh sẽ có giá trị hơn. Vấn đề chưa hẳn là cần hãng làm gì đó, mà chỉ đơn giản là mình cảm thấy nhẹ lòng vì đã làm những việc bản...
Những lần hắt hơi sổ mũi làm tôi mệt lã, phải dùng rượu uống để ngũ. Tôi cũng đang uống rượu 1 mình, viết vài dòng này cho em ( có lẽ dt chỉ bằng tuổi em tôi).
Dinh thuong dang đi vào vết xe đổ của tôi. Càng chứng minh, có...
Thiết nghĩ thi thoảng bác lên đây chia xẻ ít kinh nghiệm cũng vui rồi. Còn chuyện con người sinh lão bệnh tử là thường, sống cùng với quy luật đó thôi. Bqv nhớ trước đây bác từng kể về chuyện rang chì ô-xít bằng chảo để phục hồi bình điện, đấy cũng là thành quả đáng nể phục ở thời kỳ thiếu thốn đó.
Comment