Diferență între revizuiri ale paginii „Applications 11”
(Nu s-a afișat o versiune intermediară efectuată de același utilizator) | |||
Linia 1: | Linia 1: | ||
== Requirement == | == Requirement == | ||
− | ''Design, verify and implement a calculator. It adds, subtracts or multiplies | + | ''Design, verify and implement a calculator. It adds, subtracts or multiplies a 6 bit number to/from the current content of its accumulator. It continuously display the input number (on the first two display digits) and the current content of the accumulator (on the last three digits of the display). The accumulator's range is from 0 to 255.'' |
== Description == | == Description == | ||
− | The heart of the calculator is the | + | The heart of the calculator is the CTRL block. It receives commands from the push buttons (''PLUS'', ''MINUS'', ''MULTIPLY'' or ''CLEAR''), and sends control signals to the datapath. Apart from CTRL there are 6 registers, one for storing the result (the '''accumulator'''), and one for each of the digits used for display. The inputs shown in red are the control signals generated by the CTRL. The blocks colored in blue are sequential, clocked by the 50 MHz input clock and initialized/cleared by the common reset input. The reset is assimilated to the ''CLEAR'' command. |
[[Fișier: calc.png]] | [[Fișier: calc.png]] | ||
Linia 17: | Linia 17: | ||
* For the BCD converter see Exercise 3 from Applications 4. Adapt that solution such that to convert an 8 bit binary number to a three digit BCD number. | * For the BCD converter see Exercise 3 from Applications 4. Adapt that solution such that to convert an 8 bit binary number to a three digit BCD number. | ||
* For the ROM module see Exercise 1 from Applications 8, or Applications 10 | * For the ROM module see Exercise 1 from Applications 8, or Applications 10 | ||
− | The inputs '''bmul''', '''bsub''' and '''badd''' from the push buttons, being active 0, may be transformed to single pulse internal signals, in order to easy the | + | The inputs '''bmul''', '''bsub''' and '''badd''' from the push buttons, being active 0, may be transformed to single pulse internal signals, in order to easy the design of CTRL: |
<syntaxhighlight lang = "verilog"> | <syntaxhighlight lang = "verilog"> | ||
reg button_d; // delayed button input | reg button_d; // delayed button input | ||
Linia 45: | Linia 45: | ||
* If the inputs from push buttons are transformed to one clock cycle pulses, and supposing that the user presses one button at a time, these pulses may be directly used to control the accumulator update and to select the function of the FUNC block: | * If the inputs from push buttons are transformed to one clock cycle pulses, and supposing that the user presses one button at a time, these pulses may be directly used to control the accumulator update and to select the function of the FUNC block: | ||
+ | <syntaxhighlight lang = "verilog"> | ||
assign lda = badd_p | bsub_p | bmult_p; | assign lda = badd_p | bsub_p | bmult_p; | ||
assign selfunc = {badd_p,bsub_p,bmult_p}; | assign selfunc = {badd_p,bsub_p,bmult_p}; | ||
+ | </syntaxhighlight> | ||
* selfunc values may be defined as localparameters (ADD, SUB etc) to make the code more readable and manageable. | * selfunc values may be defined as localparameters (ADD, SUB etc) to make the code more readable and manageable. | ||
Linia 62: | Linia 64: | ||
endcase | endcase | ||
end | end | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | * The multiplexers may be described inside the top module with continuous assignments: | ||
+ | <syntaxhighlight lang = "verilog"> | ||
+ | assign w2 = sel ? w1 : w0; | ||
</syntaxhighlight> | </syntaxhighlight> |
Versiunea curentă din 23 mai 2019 05:44
Requirement
Design, verify and implement a calculator. It adds, subtracts or multiplies a 6 bit number to/from the current content of its accumulator. It continuously display the input number (on the first two display digits) and the current content of the accumulator (on the last three digits of the display). The accumulator's range is from 0 to 255.
Description
The heart of the calculator is the CTRL block. It receives commands from the push buttons (PLUS, MINUS, MULTIPLY or CLEAR), and sends control signals to the datapath. Apart from CTRL there are 6 registers, one for storing the result (the accumulator), and one for each of the digits used for display. The inputs shown in red are the control signals generated by the CTRL. The blocks colored in blue are sequential, clocked by the 50 MHz input clock and initialized/cleared by the common reset input. The reset is assimilated to the CLEAR command.
The output display configuration is stored in 5 registers which are updated cyclically, with a rate of around 100 Hz. In order to use one BCD converter and one BCD-to-segment converter, the input and accumulator values, and their digits are multiplexed digit by digit. A simple solution may be based on a counter from which 3 bits are used to generate the required control signals, as in the figure below:
Design hints
- For the BCD converter see Exercise 3 from Applications 4. Adapt that solution such that to convert an 8 bit binary number to a three digit BCD number.
- For the ROM module see Exercise 1 from Applications 8, or Applications 10
The inputs bmul, bsub and badd from the push buttons, being active 0, may be transformed to single pulse internal signals, in order to easy the design of CTRL:
reg button_d; // delayed button input
wire button_p; // one clock cycle pulse
always @(posedge clk)
button_d = button;
assign button_p = button & ~button_d; // one clock cycle pulse generated after the push button was released
- The accumulator and the FUNC block that computes its next value may be combined in a single always process:
reg [7:0] accumulator;
always @(posedge clk) begin
if(~rst)
accumulator <= 0;
else if(lda) begin
case(selfunc)
ADD: accumulator <= accumulator + din;
....
endcase
end
else
accumulator <= accumulator;
end
- If the inputs from push buttons are transformed to one clock cycle pulses, and supposing that the user presses one button at a time, these pulses may be directly used to control the accumulator update and to select the function of the FUNC block:
assign lda = badd_p | bsub_p | bmult_p;
assign selfunc = {badd_p,bsub_p,bmult_p};
- selfunc values may be defined as localparameters (ADD, SUB etc) to make the code more readable and manageable.
- To control the display update a simple counter may be used:
reg [31:0] cnt;
assign selnr = cnt[20];
assign seldig = cnt[19:18];
always @(posedge clk) begin
case(cnt[20:18])
3'b000: dig0 <= romdout;
3'b001: dig1 <= romdout;
....
endcase
end
- The multiplexers may be described inside the top module with continuous assignments:
assign w2 = sel ? w1 : w0;