[Thảo luận] Vấn đề 2 khối always và 1 biến

Trong quá trình làm các lab Verilog, đôi khi e có nhu cầu code tương tự như thế này

<!–c1–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>CODE</b> </td></tr><tr><td id=‘CODE’><!–ec1–>
always @(in) begin
*reset=1; *
end

always @(posedge CLK) begin

*if (reset) begin

  • reset=0;
    *end
              • *…
      • *end
        <!–c2–></td></tr></table><div class=‘postcolor’><!–ec2–>
        Trong đoạn trên tức là khi có 1 input nào đó thay đổi, thì cho cờ reset lên bằng 1 để khối check CLK reset lại mạch bằng một số lệnh set biến rồi trả cờ reset về 0 lại để CLK sau tiếp tục chạy các lệnh bên dưới …

Tất nhiên Quartus sẽ báo lỗi 1 biến bị thay đổi bởi 2 always block …

Câu hỏi đặt ra, mình sẽ thực hiện ý đồ đó như thế nào ?

<!–QuoteBegin-08520416+12 Mar 2011, 10:33 PM–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>QUOTE</b> (08520416 @ 12 Mar 2011, 10:33 PM)</td></tr><tr><td id=‘QUOTE’><!–QuoteEBegin–> Trong quá trình làm các lab Verilog, đôi khi e có nhu cầu code tương tự như thế này

<!–c1–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>CODE</b> </td></tr><tr><td id=‘CODE’><!–ec1–>
always @(in) begin
*reset=1; *
end

always @(posedge CLK) begin

*if (reset) begin

  • reset=0;
    *end
              • *…
      • *end
        <!–c2–></td></tr></table><div class=‘postcolor’><!–ec2–>
        Trong đoạn trên tức là khi có 1 input nào đó thay đổi, thì cho cờ reset lên bằng 1 để khối check CLK reset lại mạch bằng một số lệnh set biến rồi trả cờ reset về 0 lại để CLK sau tiếp tục chạy các lệnh bên dưới …

Tất nhiên Quartus sẽ báo lỗi 1 biến bị thay đổi bởi 2 always block …

Câu hỏi đặt ra, mình sẽ thực hiện ý đồ đó như thế nào ? <!–QuoteEnd–> </td></tr></table><div class=‘postcolor’> <!–QuoteEEnd–>
bạn đang lập trình C đó hả???
verilog là ngôn ngữ mô tả phần cứng
nếu muốn khi có input thay đổi, reset lên 1,
rùi sau đó cho reset xuống 0 thì nên cho nó ra một (hoặc nhiều) module bên ngoài.
ở đây ko có khái niệm các lệnh.
các lệnh mà bạn viết sẽ trở thành các mạch logic.
bạn nên phân tích lại mạch của mình.

Chào bạn.

  • mình ko nghĩ
    always @(in) begin
    reset=1;
    end
    nghĩa là reset sẽ lên 1 khi đầu vào in thay đổi đâu. Câu lệnh always ko phải là cứ có thay đổi là thực thi khối đó đâu.
  • tín hiệu reset, mình nghĩ cái này do bên ngoài điều khiển, sao bạn lại muốn cho xuống 0 làm gì?
  • nếu vẫn muốn thực hiện yêu cầu (tác động lên 1 biến ở cả 2 khối always) thì có thể dùng 2 biến tạm.
    <!–c1–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>CODE</b> </td></tr><tr><td id=‘CODE’><!–ec1–>
    always @(negedge CLK) begin
    ? if (gì_đó)
    ? ? ?tmp1=gì_đó; ?
    ? endif
    end

always @(posedge CLK) begin
? if (gì_đó)
? ? ?tmp2=gì_đó; ?
? endif
end

result = hàm (tmp1, tmp2)
<!–c2–></td></tr></table><div class=‘postcolor’><!–ec2–>
Đại lọai là vậy, ví dụ như bình thường mạch đếm thì chỉ có theo cạnh lên hoặc cạnh xuống của clk, nếu gán cùng biến đềm cho 2 khối always thì báo lỗi, ta có thể dùng “trick” này để tạo mạch đếm ở cả 2 cạnh của clk (ví dụ vậy thôi).

Đúng rồi. Reset là tín hiệu ngoại, tức là input, mà input thi ko đc assign, nó chỉ thay đổi do người dùng điều khiển (SW, KEY…). Còn nếu là là tín hiệu nội (reg,wire) mà thay đổi kiểu đó compile cũng sẽ báo lỗi hoặc chạy không đúng chức năng bởi 2 khối always sẽ Gen ra hai block module khác nhau mà cũng một ngõ ra output reset thì cũng chẳng có ý nghĩa j cả.

<!–QuoteBegin-08520416+14 Mar 2011, 10:55 PM–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>QUOTE</b> (08520416 @ 14 Mar 2011, 10:55 PM)</td></tr><tr><td id=‘QUOTE’><!–QuoteEBegin–> KEY0 là input, bấm KEY0 thì mạch reset về trạng thái ban đầu, nhưng mà như mình nói đó, nếu xử lý như code ở trên, thì khi còn giữ, KEY0 còn là 0 thì mạch vẫn duy trì trạng thái reset, khi nào bỏ ra (tức KEY0 bằng 1 trở lại) thì mạch mới bắt đầu vận hanh.

Mình muốn là nó chỉ reset đúng 1 lần thôi sau đó sau khi các lệnh thực thi tác vụ reset xong thì mạch tiếp tục chạy.

cái reset ở trong code là biến reg. <!–QuoteEnd–> </td></tr></table><div class=‘postcolor’> <!–QuoteEEnd–>
<!–c1–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>CODE</b> </td></tr><tr><td id=‘CODE’><!–ec1–>alway @ (Reset or posedge Clock)
begin
? ? ? ?if(Reset)
? ? ? ? ? begin
? ? ? ? ? ? ? ?value <= 0;
? ? ? ? ? end
? ? ? ?else
? ? ? ? ? begin
? ? ? ? ? ? ?value <= value+1
? ? ? ? ? end
end <!–c2–></td></tr></table><div class=‘postcolor’><!–ec2–>

bạn xem vi dụ này nha:
–khi reset = 1 thì value được reset về 0
–khi reset = 0 thì value tăng giá trị lên 1

//alway @ (Reset or posedge Clock) — nguyên cái dòng này có ý nghĩa là khi Reset thay đổi, hoặc Clock tích cực canh lên thì … thực hiện block có <b> chuc năng được mô tả trong khối Always</b>

Trở về với ý định của bạn… chỉ đơn giản là bạn thay đổi dòng value<=0 bằng đoạn mã reset giá trị, và value <=value + 1 bằng đoạn mã mô tả function của mạch

Có thể ý bạn là một block nào đó làm thay đổi giá trị của reset … nếu như vậy thì nên tạo nó ra 1 module riêng, rồi connect cái output đó với input reset

Còn về cái đoạn mã của bạn, bạn thử ngồi vẽ schemtic cái mạch bạn mô tả xem có ra không… chắc chắn là không ra

PS: mình nhắc lại là đang code verilog chứ không phải là C, cho nên cái khái niệm task, và function coi như không tồn tại. Theo mình nghĩ thì Function vs Task được hỗ trợ trong verilog chỉ để giúp người lập trình phần mềm chuyển sang phần cứng thuận tiện hơn thôi, mình vẫn chưa hiểu được cách nó generate ra mạch như thế nào <!–emo&:(–><img src=‘http://www.uit.edu.vn/forum/html/emoticons/sad.gif’ border=‘0’ style=‘vertical-align:middle’ alt=‘sad.gif’ /><!–endemo–>. Tham khảo một số code mẫu và code được tạo ra từ winzard của quartus 2 thì cũng chưa thấy nó sử dụng function vs task

<!–QuoteBegin-08520416+14 Mar 2011, 07:45 PM–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>QUOTE</b> (08520416 @ 14 Mar 2011, 07:45 PM)</td></tr><tr><td id=‘QUOTE’><!–QuoteEBegin–> Thanks all for reply …
Ở đây mình quên nói reset trong trường hợp này là reg …
Trước khi đặt câu hỏi này, thì mình đã làm thế này
<!–c1–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>CODE</b> </td></tr><tr><td id=‘CODE’><!–ec1–>
always @(posedge clk) begin

    • if (KEY0==0) begin …do something to reset… end *

    • end
      <!–c2–></td></tr></table><div class=‘postcolor’><!–ec2–>
      Thế này thì reset được và chạy được bt, nhưng nếu để ý kỹ, <b>thì nếu mình còn giữ nút KEY0, thì mạch không chạy (vì vẫn còn là 0), chỉ khi nào bỏ KEY0 ra thì mới chạy.</b>
      Ý mình muốn ở đây là khi mình bấm KEY0 một cái, mạch reset 1 lần và chạy tiếp ngay. Em dùng cách tạo ra 1 biến reg, được set lên 1 cho biến có sự thay đổi từ 1->0 của KEY0 (tức negedge), làm công tác reset xong thì trả lại về 0.
      Cụ thể như sau (tương tự như trên câu hỏi, có chỉnh sửa chút ít)
      <!–c1–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>CODE</b> </td></tr><tr><td id=‘CODE’><!–ec1–>
      reg reset;
      input KEY0, CLK;
      always @(negedge KEY0) begin
    • *reset=1; *
      end
      always @(posedge CLK) begin
    • *if (reset) begin
      • reset=0;
    • *end

    • end
      <!–c2–></td></tr></table><div class=‘postcolor’><!–ec2–><b>
      </b>* <!–QuoteEnd–> </td></tr></table><div class=‘postcolor’> <!–QuoteEEnd–>
      <!–QuoteBegin–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>QUOTE</b> </td></tr><tr><td id=‘QUOTE’><!–QuoteEBegin–>Ý mình muốn ở đây là khi mình bấm KEY0 một cái, mạch reset 1 lần và chạy tiếp ngay. Em dùng cách tạo ra 1 biến reg, được set lên 1 cho biến có sự thay đổi từ 1->0 của KEY0 (tức negedge), làm công tác reset xong thì trả lại về 0.<!–QuoteEnd–></td></tr></table><div class=‘postcolor’><!–QuoteEEnd–>
      <!–emo&:o–><img src=‘http://www.uit.edu.vn/forum/html/emoticons/ohmy.gif’ border=‘0’ style=‘vertical-align:middle’ alt=‘ohmy.gif’ /><!–endemo–> bạn mô tả chính xác cái yêu cầu của đề bài cho mình được không… Nếu bạn nói thế này thì Key0 chính là đầu vào reset… khi Key0 được nhấn lần 1 thì reset = 1 (cạnh lên) nhấn lần 2 thì reset = 0 (cạnh xuống) không cần phải gán gì hết vì nó là input.
      Còn chuyện khai báo reg cho reset thì đó là chuyện đương nhiên vì muốn gán giá trị cho 1 biến trong khối always thì nó phải có kiểu là reg …
      — Theo mình hiểu ý của bạn là khi key0 nhấn thì mạch reset lại trạng thái ban đầu.
      như thế thì key0 chính là đầu vào của xung reset… hay nói cách khác là cái input reset của module này bạn gắn vào key0. Một khi nó đã là input rồi thì không thể và không cần thiết gán giá trị <!–emo&:(–><img src=‘http://www.uit.edu.vn/forum/html/emoticons/sad.gif’ border=‘0’ style=‘vertical-align:middle’ alt=‘sad.gif’ /><!–endemo–>
      PS: đọc code bạn mình có cảm giác bạn nghĩ giống như lập trình, hồi mới mò mẫm behaviour mình cũng thế, tại vì kể ra thì nó mô tả cũng giông giống lập trình… Theo kinh nghiệm cá nhân mình thì nên code theo structure một vài mạch, rồi hãy qua behaviour. như vậy thì đỡ nhầm lẫn <!–emo&:(–><img src=‘http://www.uit.edu.vn/forum/html/emoticons/sad.gif’ border=‘0’ style=‘vertical-align:middle’ alt=‘sad.gif’ /><!–endemo–>

<!–QuoteBegin-08520416+12 Mar 2011, 10:33 PM–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>QUOTE</b> (08520416 @ 12 Mar 2011, 10:33 PM)</td></tr><tr><td id=‘QUOTE’><!–QuoteEBegin–> Trong quá trình làm các lab Verilog, đôi khi e có nhu cầu code tương tự như thế này

<!–c1–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>CODE</b> </td></tr><tr><td id=‘CODE’><!–ec1–>
always @(in) begin
*reset=1; *
end

always @(posedge CLK) begin

*if (reset) begin

  • reset=0;
    *end
              • *…
      • *end
        <!–c2–></td></tr></table><div class=‘postcolor’><!–ec2–>
        Trong đoạn trên tức là khi có 1 input nào đó thay đổi, thì cho cờ reset lên bằng 1 để khối check CLK reset lại mạch bằng một số lệnh set biến rồi trả cờ reset về 0 lại để CLK sau tiếp tục chạy các lệnh bên dưới …

Tất nhiên Quartus sẽ báo lỗi 1 biến bị thay đổi bởi 2 always block …

Câu hỏi đặt ra, mình sẽ thực hiện ý đồ đó như thế nào ? <!–QuoteEnd–></td></tr></table><div class=‘postcolor’><!–QuoteEEnd–>
-thứ nhất là 1 tín hiệu không thể được thay đổi trong 2 khối always khác nhau.
-thứ hai có lẽ bạn đang nhầm bên lập trình <!–emo&:)–><img src=‘http://www.uit.edu.vn/forum/html/emoticons/smile.gif’ border=‘0’ style=‘vertical-align:middle’ alt=‘smile.gif’ /><!–endemo–>, reset là tín hiệu input của khối always cho nên không thể gán giá trị cho nó

Về tín hiệu thì có thể viết thế này, nhưng chắc chắn sẽ báo lỗi … nhìn vào đoạn code chắc bạn cũng thấy phi lý rồi <!–emo&:)–><img src=‘http://www.uit.edu.vn/forum/html/emoticons/smile.gif’ border=‘0’ style=‘vertical-align:middle’ alt=‘smile.gif’ /><!–endemo–>… nếu cố vẽ theo đoạn code này thì khối trong if sẽ được thực hiện khi in=1 vì reset nó bằng 1. Nếu thế thì chả ai code kiểu này

<!–c1–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>CODE</b> </td></tr><tr><td id=‘CODE’><!–ec1–>
always @(posedge CLK or in) begin

      • *if(in)
          • *reset = 1;
      • if (reset) begin
    • *…
    • *reset=0;
    • *end
              • *…
      • end
        <!–c2–></td></tr></table><div class=‘postcolor’><!–ec2–>

@Mẫn :
Nếu cậu dùng <b>alway @ (Reset or posedge Clock)</b> sẽ nhận được thông báo lỗi sau :

Error (10122): Verilog HDL Event Control error at test.v(10): <b>mixed single- and double-edge expressions are not supported</b>

Còn phần code bên dưới, hiện tại mình cũng làm như cậu, với alway @ (posedge Clock). Vì clock đánh khá nhanh nên dường như k cần bắt event reset, mà bắt reset trong khối lệnh bên dưới.

Code này chạy rất tốt, nhưng chỉ là mình cảm thấy nó không được trung thực lắm. Không trung thực ở chỗ, như mình đã trình bày, đó là đúng ra khi nút dc bấm xuống 1 cái click, thì mạch đã được reset rồi, và tiếp tục chạy, chứ không chờ bật nút lên mới chạy tiếp. :expressionless:
Nếu như so sánh với các nút reset của PC, của các máy game console, hay các loại máy khác thì thấy không vừa ý lắm. Thứ hai, trong một số trường hợp, cái “delay” khi ta chưa kịp buông nút đó ra sẽ là vấn đề lớn nếu là một đồng hồ thể thao bấm giờ hoặc một thao tác gì đó khẩn cấp đến milisecond, đại loại thế.

@Triều :
<!–QuoteBegin–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>QUOTE</b> </td></tr><tr><td id=‘QUOTE’><!–QuoteEBegin–>Cho dù dùng module riêng thì nghĩa là mình cần ouput của module đó được set lên 1 (khi có xung clock chẳng hạn) rồi sau đó lại được set về 0 mãi mãi (trong khi tất cả các input đều không thay đổi giá trị). Với khả năng của mình, mình chưa thể nghĩ ra được một mạch nào mà có khả năng thực hiện điều đó. Dường như điều đó là vô lý?<!–QuoteEnd–></td></tr></table><div class=‘postcolor’><!–QuoteEEnd–>
Cái module này mình cũng đang suy nghĩ nhưng cũng chưa ra. <!–emo&:(–><img src=‘http://www.uit.edu.vn/forum/html/emoticons/sad.gif’ border=‘0’ style=‘vertical-align:middle’ alt=‘sad.gif’ /><!–endemo–>

Cám ơn Triều đã chia sẻ, những điều cậu trình bày đều hợp lý, nhưng nếu làm cách đó thì vẫn bị vướng mắc chỗ “vẫn còn reset trong khi chưa nhả button”. Mình muốn tránh trường hợp đang bấm reset mạch không chạy, chứ k phải muốn giữ như thế chi <!–emo&:D–><img src=‘http://www.uit.edu.vn/forum/html/emoticons/biggrin.gif’ border=‘0’ style=‘vertical-align:middle’ alt=‘biggrin.gif’ /><!–endemo–>.

Ở đây thực ra mình không đặt vấn để chỉ ở trong cái bài lab, chỉ là mình nghĩ ra một nhu cầu, mình cảm giác là tương lai có thể sẽ còn gặp nó, nhưng không tìm ra cách hiện thực nó nên mới đăng lên đây để cùng nhau moi móc ra nhiều trick hay để sử dụng về sau. Và kết quả đến nay cũng đã thu được một vài cách giải quyết vấn đề.

Dù vậy, cũng chưa có cách nào như ý hết. Mặc dù cái nhu cầu này mình cảm thấy là rất khả thi và cũng giản dị. <!–emo&:)–><img src=‘http://www.uit.edu.vn/forum/html/emoticons/smile.gif’ border=‘0’ style=‘vertical-align:middle’ alt=‘smile.gif’ /><!–endemo–>

Cám ơn tất cả các bạn đã góp ý, hi vọng sẽ có một giải pháp hoàn hảo.

<!–c1–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>CODE</b> </td></tr><tr><td id=‘CODE’><!–ec1–>
always@(posedge key or posedge clr)//tạo signal reset(clr) theo yêu cầu
begin

    • if (clr) clr=1’b0;
    • else clr=1’b1;
      end
      <!–c2–></td></tr></table><div class=‘postcolor’><!–ec2–>

Cái này hay ở chỗ, khi posedge key, nếu clr đang ở 0 thì cho lên 1, đồng nghĩa posedge clr, nên khối đó chạy 1 lần nữa và gán lại về 0. Lúc đầu mình cứ nghĩ cái posedge clr đó là vô nghĩa và dư thừa chứ. Nhưng nếu bỏ cái posedge clr ra thì sẽ không về 0 dc, và mạch vẫn giữ nguyên tình trạng như mình đã mô tả. Ăn tiền chỗ này nè <!–emo&:D–><img src=‘http://www.uit.edu.vn/forum/html/emoticons/biggrin.gif’ border=‘0’ style=‘vertical-align:middle’ alt=‘biggrin.gif’ /><!–endemo–>

<img src=‘http://farm3.anhso.net/upload/20110316/18/o/anhso-185951_1rr.jpg’ border=‘0’ alt=‘user posted image’ />

Đơn giản thế mà k nghĩ ra nhỉ ? <!–emo&:)–><img src=‘http://www.uit.edu.vn/forum/html/emoticons/smile.gif’ border=‘0’ style=‘vertical-align:middle’ alt=‘smile.gif’ /><!–endemo–>

Bờ-ra-vô bạn Triều và sự nhiệt tình của bạn …
Thank all you very much …

KEY0 là input, bấm KEY0 thì mạch reset về trạng thái ban đầu, nhưng mà như mình nói đó, nếu xử lý như code ở trên, thì khi còn giữ, KEY0 còn là 0 thì mạch vẫn duy trì trạng thái reset, khi nào bỏ ra (tức KEY0 bằng 1 trở lại) thì mạch mới bắt đầu vận hanh.

Mình muốn là nó chỉ reset đúng 1 lần thôi sau đó sau khi các lệnh thực thi tác vụ reset xong thì mạch tiếp tục chạy.

cái reset ở trong code là biến reg.

Thanks all for reply …
Ở đây mình quên nói reset trong trường hợp này là reg …
Trước khi đặt câu hỏi này, thì mình đã làm thế này
<!–c1–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>CODE</b> </td></tr><tr><td id=‘CODE’><!–ec1–>
always @(posedge clk) begin

    • if (KEY0==0) begin …do something to reset… end *

    • end
      <!–c2–></td></tr></table><div class=‘postcolor’><!–ec2–>
      Thế này thì reset được và chạy được bt, nhưng nếu để ý kỹ, <b>thì nếu mình còn giữ nút KEY0, thì mạch không chạy (vì vẫn còn là 0), chỉ khi nào bỏ KEY0 ra thì mới chạy.</b>
      Ý mình muốn ở đây là khi mình bấm KEY0 một cái, mạch reset 1 lần và chạy tiếp ngay. Em dùng cách tạo ra 1 biến reg, được set lên 1 cho biến có sự thay đổi từ 1->0 của KEY0 (tức negedge), làm công tác reset xong thì trả lại về 0.
      Cụ thể như sau (tương tự như trên câu hỏi, có chỉnh sửa chút ít)
      <!–c1–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>CODE</b> </td></tr><tr><td id=‘CODE’><!–ec1–>
      reg reset;
      input KEY0, CLK;
      always @(negedge KEY0) begin
    • *reset=1; *
      end
      always @(posedge CLK) begin
    • *if (reset) begin
      • reset=0;
    • *end

    • end
      <!–c2–></td></tr></table><div class=‘postcolor’><!–ec2–><b>
      </b>*

<!–QuoteBegin-08520416+15 Mar 2011, 10:48 PM–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>QUOTE</b> (08520416 @ 15 Mar 2011, 10:48 PM)</td></tr><tr><td id=‘QUOTE’><!–QuoteEBegin–>Nếu như so sánh với các nút reset của PC, của các máy game console, hay các loại máy khác thì thấy không vừa ý lắm. Thứ hai, trong một số trường hợp, cái “delay” khi ta chưa kịp buông nút đó ra sẽ là vấn đề lớn nếu là một đồng hồ thể thao bấm giờ hoặc một thao tác gì đó khẩn cấp đến milisecond, đại loại thế.

Cám ơn Triều đã chia sẻ, những điều cậu trình bày đều hợp lý, nhưng nếu làm cách đó thì vẫn bị vướng mắc chỗ “vẫn còn reset trong khi chưa nhả button”. Mình muốn tránh trường hợp đang bấm reset mạch không chạy, chứ k phải muốn giữ như thế chi <!–emo&:D–><img src=‘http://www.uit.edu.vn/forum/html/emoticons/biggrin.gif’ border=‘0’ style=‘vertical-align:middle’ alt=‘biggrin.gif’ /><!–endemo–>.

Ở đây thực ra mình không đặt vấn để chỉ ở trong cái bài lab, chỉ là mình nghĩ ra một nhu cầu, mình cảm giác là tương lai có thể sẽ còn gặp nó, nhưng không tìm ra cách hiện thực nó nên mới đăng lên đây để cùng nhau moi móc ra nhiều trick hay để sử dụng về sau. Và kết quả đến nay cũng đã thu được một vài cách giải quyết vấn đề. <!–QuoteEnd–></td></tr></table><div class=‘postcolor’><!–QuoteEEnd–>
Uh, bây giờ thì mình đã hiểu ý muốn của Toàn, và mình tin là mọi người cũng đã hiểu.
Và, Triều cũng đã nghĩ ra được mạch điện thỏa mãn yêu cầu của Toàn, nó như sau:
<img src=‘http://i787.photobucket.com/albums/yy155/xuantrieu123/Reset_by_the_edge_of_input.jpg’ border=‘0’ alt=‘user posted image’ />
Ở trên, Triều giả sử nếu không có reset thì output Q được lấy giá trị theo D, còn thực tế như thế nào thì tùy Toàn.
Nhìn mạch trên thì ắc Toàn sẽ hiểu nguyên lý hoạt động của mạch và sẽ thấy nó thỏa mãn yêu cầu của Toàn?
Nếu vậy, code cho nó sẽ là:
<!–c1–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>CODE</b> </td></tr><tr><td id=‘CODE’><!–ec1–>module test(D,key,clk,Q);
input D,clk,key;
output reg Q;
reg clr;
always@(posedge key or posedge clr)//tạo signal reset(clr) theo yêu cầu
begin
if(clr)clr=1’b0;
else clr=1’b1;
end
always@(posedge clk or posedge clr)//dùng signal này để reset lại Q
begin
if(clr)Q=1’b0;
else Q=D;
end
endmodule <!–c2–></td></tr></table><div class=‘postcolor’><!–ec2–>
Cuối cùng, Triều đã mô phỏng thử và kết quả như sau:
<img src=‘http://i787.photobucket.com/albums/yy155/xuantrieu123/reset_simulation-1-1.jpg’ border=‘0’ alt=‘user posted image’ />

Is that right?
Regards!

PS: Sorry, Triều đã test với key nhấn xuống thì key=1 cho dễ simulation. Toàn có thể viết lại đoạn code tạo signal reset thay vì posedge key là negedge key! (hình như Triều nói hơi bị thừa <!–emo&:D–><img src=‘http://www.uit.edu.vn/forum/html/emoticons/biggrin.gif’ border=‘0’ style=‘vertical-align:middle’ alt=‘biggrin.gif’ /><!–endemo–>)

<!–QuoteBegin-08520229+14 Mar 2011, 11:51 PM–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>QUOTE</b> (08520229 @ 14 Mar 2011, 11:51 PM)</td></tr><tr><td id=‘QUOTE’><!–QuoteEBegin–>Có thể ý bạn là một block nào đó làm thay đổi giá trị của reset … nếu như vậy thì nên tạo nó ra 1 module riêng, rồi connect cái output đó với input reset
<!–QuoteEnd–></td></tr></table><div class=‘postcolor’><!–QuoteEEnd–>
Cho dù dùng module riêng thì nghĩa là mình cần ouput của module đó được set lên 1 (khi có xung clock chẳng hạn) rồi sau đó lại được set về 0 mãi mãi (trong khi tất cả các input đều không thay đổi giá trị). Với khả năng của mình, mình chưa thể nghĩ ra được một mạch nào mà có khả năng thực hiện điều đó. Dường như điều đó là vô lý?

Về phía bạn Toàn, tôi nghĩ là bạn đang cần input khác chứ không phải nút nhấn key, như switch chẳng hạn. Vì nếu bạn cần key[0] để reset lại mạch thì thật sự bạn rảnh thật. Mắc mới gì bạn lại cố giữ phím key[0] mà mạch vẫn chạy tiếp mà lại không thả nó ra?

Chắc có lẽ bạn đang cần dùng switch để reset hay preset cho một output nào đó. Nếu điều tôi nói là đúng, bạn có thể làm theo ý tưởng sau:
Tạo 1 module (để sau này gọi lại) với 2 input key và sw, 2 output pre và clr (sau này sẽ nối với preset và clear của fipflop)
module có chức năng như sau:
<!–c1–></div><table border=‘0’ align=‘center’ width=‘95%’ cellpadding=‘3’ cellspacing=‘1’><tr><td><b>CODE</b> </td></tr><tr><td id=‘CODE’><!–ec1–>pre=sw & ~key;
clr=~sw & ~key;<!–c2–></td></tr></table><div class=‘postcolor’><!–ec2–>

Khi đó, nếu ta nối block này với flipflop như đã nói, thì:

  • Nếu nhấn phím key (key=0),
  • Nếu sw=1, pre=1 và clr=0 (flipflop set lên 1 cho output Q)
  • Nếu sw=0, pre=0 và clr=1 (flipflop reset về 0 cho output Q)
  • Nếu thả phím key (key=1) thì pre=clr=0 (mạch tiếp tục chạy mà không ảnh hưởng tới giá trị của sw!

Hy vọng những điều tôi nói là đúng. Chúc bạn thành công!