Mình muốn các bạn hãy đóng góp nhiều đoạn mã viết bằng VHDL để cùng nhau tham khảo. Hãy chia sẻ để được nhiều hơn. Vì người Việt !!!!!!!!
Thông báo
Collapse
No announcement yet.
mã viết bằng VHDL
Collapse
X
-
đoạn mã hiển thị quét
Code:library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; package khaibao is type dl_quet is array(5 downto 0) of std_logic_vector(3 downto 0); function chuyen(vao:std_logic_vector(2 downto 0)) return integer; end khaibao; package body khaibao is function chuyen(vao:std_logic_vector(2 downto 0)) return integer is variable tam:integer; begin case(vao) is when "000" => tam := 0; when "001" => tam := 1; when "010" => tam := 2; when "011" => tam := 3; when "100" => tam := 4; when "101" => tam := 5; when others => tam := 0; end case; return (tam); end function chuyen; end khaibao; library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use work.khaibao.all; entity dynamic_display is Port ( clk,rst : in STD_LOGIC; dl : out STD_LOGIC_VECTOR (7 downto 0); q : out STD_LOGIC_VECTOR (5 downto 0)); end dynamic_display; architecture Behavioral of dynamic_display is signal tinhieu: dl_quet; signal vt : std_logic_vector(2 downto 0):="000"; begin xu_li:process(clk,rst) variable t1:integer:=0; variable t3:integer:=0; begin if (rst='0') then for t1 in 0 to 5 loop tinhieu(t1) <= "0000"; end loop; elsif (clk'event and clk='1') then -- clk 1KHz t1 := chuyen(vt); if (t3=1000) then tinhieu(0) <= tinhieu(0) + 1; t3 := 0; else t3 := t3 + 1; end if; if(tinhieu(t1)=10) then tinhieu(t1) <= "0000"; if(t1<5) then tinhieu(t1+1) <= tinhieu(t1+1) + 1; end if; end if; if (vt=5) then vt <= "000"; else vt <= vt + 1; end if; end if; end process xu_li; giai_ma:process(tinhieu,vt) variable t2:integer; begin t2 := chuyen(vt); case (t2) is when 0 => q <= "000001"; when 1 => q <= "000010"; when 2 => q <= "000100"; when 3 => q <= "001000"; when 4 => q <= "010000"; when 5 => q <= "100000"; when others => q <= "000001"; end case; case (tinhieu(t2)) is --"abcdefgDP" when "0000" => dl <= "11111100"; when "0001" => dl <= "01100000"; when "0010" => dl <= "11011010"; when "0011" => dl <= "11110010"; when "0100" => dl <= "01100110"; when "0101" => dl <= "10110110"; when "0110" => dl <= "10111110"; when "0111" => dl <= "11100000"; when "1000" => dl <= "11111110"; when "1001" => dl <= "11110110"; when others => dl <= "11111100"; end case; end process giai_ma; end Behavioral;
-
Mã nguồn chia tần số:
-----------------------------------------
LIBRARY ieee;
USE ieee.Std_logic_1164.ALL;
USE ieee.Std_logic_unsigned.ALL;
-----------------------------------------
ENTITY clk_div IS
GENERIC(baudDivide : std_logic_vector(7 downto 0) :=
"10101110");
PORT(
clk : in std_logic;
clk16 : inout Std_logic
);
END clk_div;
-----------------------------------------
ARCHITECTURE rtl OF clk_div IS
SIGNAL cnt_div : Std_logic_vector(7 DOWNTO 0);
BEGIN
process (CLK, cnt_div)
begin
if (Clk = '1' and Clk'event) then
if (cnt_div = baudDivide) then
cnt_div <= "00000000";
else
cnt_div <= cnt_div + 1;
end if;
end if;
end process;
process (cnt_div, clk16, CLK)
begin
if CLK = '1' and CLK'Event then
if cnt_div = baudDivide then
clk16 <= not clk16;
else
clk16 <= clk16;
end if;
end if;
end process;
END rtl;
-----------------------------------------
Comment
-
Mọi người tham khảo thôi, chứ còn khi lập trình cho phần nhúng thế này, thì chỉ cần mình hiểu thế nào và mô tả thế nào thui mà, chứ cứ có ý tưởng và thạo ngôn ngữ là viết OK rùi.
Code bộ cộng N bit:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity adder is
generic (N : natural :=16);
port (A : in std_logic_vector(N-1 downto 0);
B : in std_logic_vector(N-1 downto 0);
Cin : in std_logic;
S : out std_logic_vector(N-1 downto 0);
Cout : out std_logic
);
end adder;
architecture dataflow of adder is
signal A1: std_logic_vector(N downto 0);
signal B1: std_logic_vector(N downto 0);
signal S1: std_logic_vector(N downto 0);
begin
A1 <= '0' & A;
B1 <= '0'& B;
S1 <= A1 + B1 + Cin;
Cout <= S1(N);
S <= S1(N-1 downto 0);
end dataflow;
Comment
-
Chào bạn Siskin_lion,
Nói thật với bạn mạch nhân, chia tần số bao giờ cũng phải dùng PLL, mấy loại dùng bộ đếm này là trò lừa học sinh. Có lẽ từ thời xưa người ta dùng cách này hay không thì tớ không biết nhưng từ lúc tớ đi làm đến giờ chẳng thấy cái mạch nhân chia tần số nào mà lại dùng bộ đếm kiểu này cả. Tín hiệu tần số có yêu cầu rất cao về jitter, screw... Ngay cả tín hiệu clock người ta cũng không thể synthesize một cách bừa bãi được. Các mạch clock gate... thường phải thêm vào thuộc tích "dont touch" để tránh synthesize bậy bạ. Tớ viết bài này không có ý chỉ trích gì bạn hết mà là để "giải độc" cho nhiều bạn chưa có kinh nghiệm. Không biết có phải ở VN dạy cho sinh viên những kỹ thuật cách đây hàng chục năm hay không mà sao khá nhiều bạn hiểu sai về kỹ thuật nhân chia tần số.
Nguyên văn bởi siskin_lion Xem bài viếtMã nguồn chia tần số:
Comment
-
Bạn Rommel.de này, trong mạch FPGA, mình đã làm, đã chạy thử, Xilin biên dịch đc bình thường và nạp vào mach FPGA chạy đúng đó thui, còn đi làm thực tế ở các công ty ngoài thì mình chưa có kinh nghiệm nên chưa biết, nếu bạn đã góp ý, mình coi đó là kinh nghiệm cho sau này, còn hiện tại, khi còn là sinh viên, các chương trình code để mô phỏng, giúp sinh viên hiểu cách viết code, cách mô phỏng là chủ yếu, nên mình post bài cho các bạn sinh viên tham khảo thui, đó cũng là những file khi mình bắt đầu viết chương trình cho FPGA, những ngày đó, mình thực sự đam mê và thích. Còn nếu các bạn đã tìm hiểu sâu hơn rùi, các bạn biết trong FPGA có 4 bộ DCM để chia tần số, thiế́t lập hệ số là chính xác luôn từ thạch anh trong FPGA. Nhưng bạn phải hiểu nhiều sâu đc FPGA đã, chứ k phải cho các bạn mới bắt đầu học viết VHDL hay viết chưa đc nhiều. Cảm ơn sự đóng góp của mọi ng!
Comment
-
Nguyên văn bởi Rommel.de Xem bài viếtChào bạn Siskin_lion,
Nói thật với bạn mạch nhân, chia tần số bao giờ cũng phải dùng PLL, mấy loại dùng bộ đếm này là trò lừa học sinh. Có lẽ từ thời xưa người ta dùng cách này hay không thì tớ không biết nhưng từ lúc tớ đi làm đến giờ chẳng thấy cái mạch nhân chia tần số nào mà lại dùng bộ đếm kiểu này cả. Tín hiệu tần số có yêu cầu rất cao về jitter, screw... Ngay cả tín hiệu clock người ta cũng không thể synthesize một cách bừa bãi được. Các mạch clock gate... thường phải thêm vào thuộc tích "dont touch" để tránh synthesize bậy bạ. Tớ viết bài này không có ý chỉ trích gì bạn hết mà là để "giải độc" cho nhiều bạn chưa có kinh nghiệm. Không biết có phải ở VN dạy cho sinh viên những kỹ thuật cách đây hàng chục năm hay không mà sao khá nhiều bạn hiểu sai về kỹ thuật nhân chia tần số.
Comment
-
Nguyên văn bởi siskin_lion Xem bài viếtCòn nếu các bạn đã tìm hiểu sâu hơn rùi, các bạn biết trong FPGA có 4 bộ DCM để chia tần số, thiế́t lập hệ số là chính xác luôn từ thạch anh trong FPGA. Nhưng bạn phải hiểu nhiều sâu đc FPGA đã, chứ k phải cho các bạn mới bắt đầu học viết VHDL hay viết chưa đc nhiều. Cảm ơn sự đóng góp của mọi ng!
Sẽ rất tốt nếu bạn bỏ công hướng dẫn từng bước tới kết quả mô phỏng luôn, vì với các bạn sinh viên không có điều kiện thực hành nếu chỉ đơn thuần nhìn code sẽ khó hình dung
Comment
-
Chào bạn Siskin_lion,
Tớ lúc đầu không định viết tiếp để tránh những căng thẳng không cần thiết, nhưng cuối cùng tớ vẫn là muốn "giải độc" cho nhiều bạn bị đầu độc về mạch chia tần số này. Nhân tiện tớ viết một đoạn code tương tự như mạch chia tần số để bạn so sánh.
Code:module pseudo_clock_divider (clk, rst, data_in, data_out); parameter DATA_WIDTH=8; parameter DIVIDE=3; input clk, rst; input [DATA_WIDTH-1:0] data_in; output [DATA_WIDTH-1:0] data_out; reg [DATA_WIDTH-1:0] data_out; reg [3:0] count; //Create couter for pseudo clock divider always @ (posedge clk) if (rst) count<=4'b0000; else if (count==(DIVIDE-1)) count<=4'b0000; else count<=count+1; //pseudo clock divider always @ (posedge clk) if (rst) data_out<={DATA_WIDTH{1'b0}}; else if(count==(DIVIDE-1)) data_out<=data_in; endmodule // pseudo_clock_divider
Tớ làm về ASIC nên không có nhiều kinh nghiệm về FPGA nhưng chắc chắn ASIC khó hơn FPGA không phải 1 bậc. Cho dù làm một ví dụ mạch đơn giản cho sinh viên thì việc tổng hợp tín hiệu đồng hồ bằng flipflop đã là sai về nguyên tắc thiết kế rồi. Bạn thử đem tín hiệu của mạch chia tần số này rồi dùng làm clock cho một phần mạch khác xem hoạt động của nó thế nào. Tớ lấy ví dụ flipflop của bạn rất dễ bị ảnh hưởng bới những mạch xung quanh do crosstalk (mạch đồng hồ thật sự luôn có bảo vệ so với những mạch bên cạch). Nếu vậy tín hiệu đồng hồ làm sao mà ổn định được. Tớ nói ví von một tí thì so sánh tín hiệu đồng hồ tạo ra từ PLL và từ bộ đếm mà bạn viết cũng như kim cương so với pha lê vậy. Người không chuyên có thể thấy tương tự nhưng thật ra khác xa nhau lắm. Tớ không muốn những bạn khác có ít kinh nghiệm hiểu lầm mà thôi.
Nhân tiện tớ thấy trên mạng có một bài viết về tầu ngầm bị cháy vì dùng đã "độ" dùng nắp chai bia thay cho vòng đệm (theo kiểu pha lê thay cho kim cương). Các bạn đọc cho vui.
Tàu ngầm huyền thoại Liên Xô hỏng 'vì nắp chai bia' - VnExpress
Nguyên văn bởi siskin_lion Xem bài viếtBạn Rommel.de này, trong mạch FPGA, mình đã làm, đã chạy thử, Xilin biên dịch đc bình thường và nạp vào mach FPGA chạy đúng đó thui, còn đi làm thực tế ở các công ty ngoài thì mình chưa có kinh nghiệm nên chưa biết, nếu bạn đã góp ý, mình coi đó là kinh nghiệm cho sau này, còn hiện tại, khi còn là sinh viên, các chương trình code để mô phỏng, giúp sinh viên hiểu cách viết code, cách mô phỏng là chủ yếu, nên mình post bài cho các bạn sinh viên tham khảo thui, đó cũng là những file khi mình bắt đầu viết chương trình cho FPGA, những ngày đó, mình thực sự đam mê và thích. Còn nếu các bạn đã tìm hiểu sâu hơn rùi, các bạn biết trong FPGA có 4 bộ DCM để chia tần số, thiế́t lập hệ số là chính xác luôn từ thạch anh trong FPGA. Nhưng bạn phải hiểu nhiều sâu đc FPGA đã, chứ k phải cho các bạn mới bắt đầu học viết VHDL hay viết chưa đc nhiều. Cảm ơn sự đóng góp của mọi ng!Last edited by Rommel.de; 06-10-2012, 02:28.
Comment
-
Thật ra dùng chia tần bằng counter trong FPGA/CPLD cũng được, nhưng phải hiểu một số thứ:
- Tín hiệu clock luôn phải được tải bằng các buffer mạnh (clock buffer), clock buffer này nằm gần các PLL/DCM để buffer đầu ra của các DCM
- Khi chia tần bằng counter, tín hiệu clock của bạn sẽ là đầu ra của 1 flip-flop và tín hiệu này được tải ngược trở về gần Pll/DCM mà ở đó có các clock buffer rồi mới tỏa ra các flip flop còn lại --> điều này dẫn đến việc trễ (skew) của clock sinh ra và clock nguồn ban đầu => không nên, khi chuyển data giũa các clock này rất phức tạp
- Trong FPGA và CPLD vì PLL/DCM có hạn, nhiều khi không có nên đôi khi các mạch logic cùi cùi ví dụ như serial uart, spi, i2c, hoặc mạch nhấp nháy led vần có thể dùng mấy clock vài trăm kHz bằng cách dùng counter
Comment
-
Mình có post một bài ở thread "tâm sự về FPGA", mình copy lại đây:
a) Clocks:
Ai học mạch số rồi thì biết, clock là thành phần quan trong nhì trong mạch (sau nguồn điện), như nhịp tim vậy, mạch mà không chạy là kiểm tra coi thằng Power có không, rồi đến clock có chạy không. Do đó tín hiệu clock được ưu ái trên FPGA:
- Clock được đưa vào từ những chân riêng.
- Clock được dẫn trên hệ thống dẫn riêng và được lái (drive) bằng buffers đặc biệt gọi là Global Buffers (Xilinx gọi là BUFG, Altera gọi là Clock Control Block). Hệ thống clock này được gọi là Global Clock Network. Clock được ưu ái như vậy để clock có thể đến tất cả các Flip-flop trên chip tại cùng một thời điểm (hay ít ra là gần như vậy) ( low skew). Bạn nào không rõ khái niệm clock skew thì có thể đọc ở đây Clock skew - Wikipedia, the free encyclopedia.
Những điều này có ý nghĩa thế nào khi thiết kế? Những điều này có ý nghĩa là bạn không thể coi clock như tín hiệu bình thường. Ví dụ như bạn không thể (hoặc không nên) đảo clock một cách tùy ý, để tạo ra clock khác ngược với clock đang có, và cho clock này chạy một mạch khác. Hoặc một ví dụ khác là bạn cần một mạch chạy ở clock 1MHz, clock bạn đang có là 50MHz, bạn dùng code VHDL/Verilog viết một bộ đếm để chia clock từ 50MHz xuống 1MHz như sau:
process(clk_50M)
if(rising_edge(clk_50M)) then
if(counter=24) then counter <= 0 else counter <= counter+1; end if;
if(counter=0) then clk_1M <= not clock_1M; end if;
end if;
end process;
Sau đó, bạn dùng slow_clk này để chạy một process khac
process(clk_1M)
begin
if(rising_edge(clk_1M)) then
....
end if;
end process;
Khi bạn dùng như vậy, không có gì sai, nhưng về nguyên tắc thì không nên ... một số phần mềm sẽ tư động phát hiện clk_1M là clock và dùng Global Clock Network cho tín hiệu này. Một số phần mềm sẽ không thông minh như vậy. Ví dụ như ISE sẽ hiện thông báo sau:
-----------------------------------+------------------------+-------+
Clock Signal | Clock buffer(FF name) | Load |
-----------------------------------+------------------------+-------+
clk_50M | BUFGP | 9 |
clk_1M | NONE(cntri_1) | 8 |
-----------------------------------+------------------------+-------+
INFO:Xst:2169 - HDL ADVISOR - Some clock signals were not automatically buffered by XST with BUFG/BUFR resources. Please use the buffer_type constraint in order to insert these buffers to the clock signals to help prevent skew problems.
Trong bảng thông báo trên, Xilinx báo là đã tự động tạo Clock Buffer cho tín hiệu clk_50M, còn clk_1M thì không chèn thêm Clock Buffer nào và kèm theo bảng thông báo.
Đó là một ví dụ nhỏ, để các bạn mới làm quen với FPGA phải nhớ là CLOCK không giống các tín hiệu khác và phải xử lý riêng. Các tài nguyên để sử dụng trong Xilinx cho vấn đề clock là:
- DCM/PLL
- BUFGMUX
Comment
-
chào cả nhà: mình đang có cái chương trình này mà chưa hiểu. nhờ cả nhà giúp mình
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.CALC1_PAK.all;ENTITY CNTRL_FSM_TB_vhd IS
END CNTRL_FSM_TB_vhd;
ARCHITECTURE behavior OF CNTRL_FSM_TB_vhd IS
COMPONENT CNTRL_FSM
PORT(
DATA_FRAME : IN MY_RECORD;
CLK : IN std_logic;
RESET : IN std_logic;
A_OP : OUT std_logic_vector(3 downto 0);
B_OP : OUT std_logic_vector(3 downto 0);
C_IN : OUT std_logic;
OP_CODE : OUT std_logic_vector(3 downto 0);
EXP : OUT std_logic_vector(3 downto 0);
MEM_EN : OUT std_logic;
ALU_EN : OUT std_logic ;
COMP_EN : OUT std_logic ;
ADDR : OUT std_logic_vector(2 downto 0) );
END COMPONENT;
SIGNAL DATA_FRAME : MY_RECORD := ("0000", "0000","0000",'0',"0000");
SIGNAL CLK : std_logic := '0';
SIGNAL RESET : std_logic := '0';
SIGNAL A_IN, B_IN : std_logic_vector(3 downto 0);
SIGNAL C_IN : std_logic;
SIGNAL OP_CODE : std_logic_vector(3 downto 0);
SIGNAL EXP : std_logic_vector(3 downto 0);
SIGNAL ALU_EN, MEM_EN, COMP_EN : std_logic;
SIGNAL ADDR : std_logic_vector(2 downto 0);
BEGIN
uut: CNTRL_FSM PORT MAP(
DATA_FRAME => DATA_FRAME,
CLK => CLK,
RESET => RESET,
A_IN => A_IN,
B_IN => B_IN,
C_IN => C_IN,
OP_CODE => OP_CODE,
EXP => EXP,
ALU_EN => ALU_EN, MEM_EN => MEM_EN, COMP_EN => COMP_EN ,
ADDR => ADDR );
CLK <= not CLK after 20 ns;
RESET <= '1' after 10 ns, '0' after 25 ns;
tb : PROCESS
BEGIN
DATA_FRAME <= ("1000", "0100","0000",'0',"0000");
wait for 100 ns;
DATA_FRAME <= ("1000", "0100","0101",'0',"0000");
wait for 100 ns;
DATA_FRAME <= ("1000", "0100","0100",'0',"0000");
wait; -- will wait forever
END PROCESS;
END TEST;
Comment
-
Xin code VHDL
Các pro VHDL có thể cho em xin ít tài liệu, hoặc viết code càng tốt ạ
Tình hình là em có một đề tài là đọc ghi vi xử lý sử dụng chuẩn JTAG, mà ở đây cụ thể là FPGA trong kit spatan 3E của Xilinx.
Giờ em phải định nghĩa cấu hình cho JTAg trong FPGA và định nghĩa Register trong FPGA bằng code VHDL.
Mong nhận được phản hồi ạ!
Comment
-
Nguyên văn bởi sangnt_55 Xem bài viếtCác pro VHDL có thể cho em xin ít tài liệu, hoặc viết code càng tốt ạ
Tình hình là em có một đề tài là đọc ghi vi xử lý sử dụng chuẩn JTAG, mà ở đây cụ thể là FPGA trong kit spatan 3E của Xilinx.
Giờ em phải định nghĩa cấu hình cho JTAg trong FPGA và định nghĩa Register trong FPGA bằng code VHDL.
Mong nhận được phản hồi ạ!
Tôi không hiểu ý bạn muốn hỏi lắm. Cái này có phải làm cái bạn muốn làm hay k: Configuration PROMs
ở mục "Configuration PROMs Application Notes" ấy.
Regards,
Comment
Bài viết mới nhất
Collapse
-
Trả lời cho Hỏi cách điều chế xungbởi thetungBạn cho qua cái Tờ ri gơ Sờ mít ấy ......
-
Channel: Kỹ thuật điện tử tương tự
16-12-2024, 11:26 -
-
Trả lời cho Hỏi cách điều chế xungbởi nguyendinhvanCó gì mà khó ?
Răn cưa vuông đây
...-
Channel: Kỹ thuật điện tử tương tự
15-12-2024, 23:36 -
-
Trả lời cho hỏi về tụ điệnbởi ndp62Chữ " VENT" không phải là tên hãng sx tụ đâu ,vó thế là 1 ký hiệu liên quan tụ lowesr ?
-
Channel: Điện thanh
15-12-2024, 18:24 -
-
Trả lời cho Thắc mắc về nguồn tổ ong 12vbởi bqvietTrừ trường hợp công suất (rất) thấp, hầu như tất cả các loại nguồn xung thông thường đều có tụ nhỏ 1 - 10nF nối giữa sơ cấp và thứ cấp, để thoát nhiễu và để chống hiện tượng tương tự tĩnh điện. Vụ này đã thảo luận vài...
-
Channel: Điện tử dành cho người mới bắt đầu
14-12-2024, 22:02 -
-
Trả lời cho Thắc mắc về nguồn tổ ong 12vbởi namlangnhoE thử 3 cái nguồn nó đều giống nhau. Nên e làm tiếp địa luôn.
-
Channel: Điện tử dành cho người mới bắt đầu
14-12-2024, 19:58 -
-
Trả lời cho Thắc mắc về nguồn tổ ong 12vbởi mèomướpDạ chú sắm con át chống giật và thay nguồn tổ ong khác cho an toàn ạ. Đa phần nguồn xung đều xả nhiễu của bên thứ cấp về điện lưới qua 1 con tụ nên cảm giác tê sẽ khó xác định rõ ràng là do rò điện hay là nó vốn vậy...
-
Channel: Điện tử dành cho người mới bắt đầu
14-12-2024, 18:51 -
-
bởi namlangnhoXin chào mọi người. E có sử dụng 1 cục nguồn tổ ong 12v-30A chạy đèn led xe trà sữa. Mà thợ thi công bị rò điện nên điện rò ra khung xe. E dùng đồng hồ đo điện ở khung xe và cả output thì thấy có dòng điện xoay chiều hơn 100v. Nên chạm...
-
Channel: Điện tử dành cho người mới bắt đầu
14-12-2024, 00:12 -
-
bởi Manh.n.trCác bác cho em hỏi cách điều chế xung răng cưa sang xung vuông với ạ. Em đang thấy khó ạ...
-
Channel: Kỹ thuật điện tử tương tự
13-12-2024, 20:46 -
-
Trả lời cho hỏi về thiết kế mạch tuần tự trên proteusbởi Hatruong1309
-
Channel: Hỗ trợ học tập
12-12-2024, 00:33 -
-
bởi Hatruong1309Cho e hỏi là phần chân X thì nối cái j thì mạch mới chạy được ạ và kiểm tra đúng sai kiểu j ạ
Đề bài thiết kế mạch dãy đồng bộ nhận biết dãy tín hiệu vào ở dạng nhị phân được đưa liên tiếp ở đầu vào X và được đồng...-
Channel: Hỗ trợ học tập
12-12-2024, 00:33 -
Comment