Advertisement
Cloud9Jeffery

Untitled

Apr 25th, 2021
680
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //INSTRUCTIONS
  2. //Extend the vending machine model from Section 16.3 to allow
  3. //U.S.A. currencies from a nickel to twenty dollar bill (0.05, 0.10, 0.25, 0.50, 1.00, 2.00, 5.00, 10.00, and 20.00).
  4. //Add a cancel button which  will return the currency inserted.
  5. //Add a two character selection criteria with first character being from A-H and second character from 1-9.
  6. //Read a price file for each of the 72 items.
  7. //Add a current monies held for each type of currency (also read from a file)
  8. //and after dispensing return the residual using the minimum number of currency unit.
  9. //Write a testbench which validates each of these functions.
  10.  
  11.  
  12.  
  13.  
  14. //d flip flop for state control
  15. module DFF(clk, in, out);
  16.     parameter n = 1;    //width
  17.     input clk;
  18.     input [n-1:0] in;
  19.     output [n-1:0] out;
  20.     reg [n-1:0] out;
  21.  
  22.     //posedge triggers on rising edge  of clock signal
  23.     always @(posedge clk)
  24.         out = in;
  25. endmodule
  26.  
  27.  
  28. //mux3   - pg 157
  29. //three input mux with one-hot select (arbitrary width)
  30. module Mux3(a2, a1, a0, s, b);
  31.     parameter k = 1;
  32.     input [k-1:0] a2, a1, a0;   //inputs
  33.     input [2:0] s;              //one-hot selet
  34.     output [k-1:0] b;
  35.     assign b = ({k{s[2]}} & a2) |
  36.                     ({k{s[1]}} & a1) |
  37.                     ({k{s[0]}} & a0);
  38. endmodule
  39.  
  40.  
  41. //addsub - pg 221
  42. // add a+b or subtract a - b, check for overflow
  43. module AddSub(a, b, sub, s, ovf);
  44.     parameter n = 8;
  45.     input [n-1:0] a, b;
  46.     input sub;              //subtract if sub=1, otherwise add
  47.     output [n-1:0] s;
  48.     output ovf;             //1 if overflow
  49.     wire c1, c2;            //carry out of last two bits
  50.     assign ovf = c1 ^ c2;   //overflow if signs don't match
  51.  
  52.     //add non sign bits
  53.     assign {c1, s[n-2:0]} = a[n-2:0] + (b[n-2:0] ^ {n-1{sub}}) + sub;
  54.     //add sign bits
  55.     assign {c2, s[n-1]} = a[n-1] + (b[n-1] ^ sub) + c1;
  56. endmodule
  57.  
  58.  
  59.  
  60. module VendingMachine(clk, rst, nickel, dime, quarter, dispense, done, price, serve, change);
  61.     parameter n = `DWIDTH;
  62.     input clk, rst, nickel, dime, quarter, dispense, done;
  63.     input [n-1:0] price;
  64.     output serve, change;
  65.  
  66.     wire enough, zero, sub;
  67.     wire [3:0] selval;
  68.     wire [2:0] selnext;
  69.  
  70.     VendingMachineControl vmc(clk, rst, nickel, dime, quarter, dispense, done, enough, zero, serve, change, selval, selnext, sub);
  71.  
  72.     VendingMachineData #(n) vmd(clk, selval, selnext, sub, price, enough, zero);
  73. endmodule
  74.  
  75.  
  76.  
  77.  
  78. module VendingMachineControl(clk, rst, nickel, dime, quarter, dispense, done, enough, zero, serve, change, selval, selnext, sub);
  79.     input clk, rst, nickel, dime, quarter, dispense, done, enough, zero;
  80.     output serve, change, sub;
  81.     output [3:0] selval;
  82.     output [2:0] selnext;
  83.     wire [`SWIDTH-1:0] state, next;     //current and next state
  84.     reg [`SWIDTH-1:0] next1;            //next state w/o reset
  85.  
  86.     //outputs
  87.     wire first;     //true during first cycle of serve1 or change1
  88.     wire serve1 = (state == `SERVE1);
  89.     wire change1 = (state == `CHANGE1);
  90.     assign serve = serve1 & first;
  91.     assign change = chang1 & first;
  92.  
  93.     //datapath controls
  94.     wire dep = (state == `DEPOSIT);
  95.     // price, 1, 2, 5
  96.     wire [3:0] selval = {(dep & dispense),
  97.                          ((dep & nickel) | change),
  98.                          (dep & dime),
  99.                          (dep & quarter)};
  100.     // amount, sum, 0
  101.     wire selv = (dep & (nickel | dime | quarter | (dispense & enough))) |
  102.                 (change & first);
  103.     wire [2:0] selnext = {~(selv | rst), ~rst & selv,rst};
  104.  
  105.     //subtract
  106.     wire sub = (dep & dispense) | change;
  107.  
  108.     //only do actions on first cycle of serve1 or change1
  109.     wire nfirst = !(serve1 | change1);
  110.     DFF #(1) first_reg(clk, nfirst, first);
  111.  
  112.     //state register
  113.     DFF #(`SWIDTH) state_reg(clk, next, state);
  114.  
  115.     //next state logic
  116.     always @(*) begin
  117.         casex({dispense, enough, done, zero, state})
  118.             {4'b11xx, `DEPOSIT}: next1 = `SERVE1;   //dispense & enough
  119.             {4'b0xxx, `DEPOSIT}: next1 = `DEPOSIT;  
  120.             {4'bx0xx, `DEPOSIT}: next1 = `DEPOSIT;  
  121.             {4'bxx1x, `SERVE1}:  next1 = `SERVE2;   //done
  122.             {4'bxx0x, `SERVE1}:  next1 = `SERVE1;
  123.             {4'bxx01, `SERVE2}:  next1 = `DEPOSIT;  //~done & zero
  124.             {4'bxx00, `SERVE2}:  next1 = `CHANGE1;  //~done & ~zero
  125.             {4'bxx1x, `SERVE2}:  next1 = `SERVE2;   //done
  126.             {4'bxx1x, `CHANGE1}: next1 = `CHANGE2;  //done
  127.             {4'bxx0x, `CHANGE1}: next1 = `CHANGE1;  //done
  128.             {4'bxx00, `CHANGE2}: next1 = `CHANGE1;  //~done & ~zero
  129.             {4'bxx01, `CHANGE2}: next1 = `DEPOSIT;  //~done & zero
  130.             {4'bxx1x, `CHANGE2}: next1 = `CHANGE2;  //~done & ~zero
  131.         endcase
  132.     end
  133.  
  134.     //reset next state
  135.     assign next = rst ? `DEPOSIT : next1;
  136. endmodule
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143. module VendingMachineData(clk, selval, selnext, sub, price, enough, zero);
  144.     parameter n = 6;
  145.     input clk, sub;
  146.     input [3:0] selval;     //price, 1, 2, 5
  147.     input [2:0] selnext;    //amount, sum, 0
  148.     input [n-1:0] price;    //price of soft drink - in nickels
  149.     output enough;          //amount > price
  150.     output zero;            //amount = zero
  151.    
  152.     wire [n-1:0] sum;       //output of add/subtract unit
  153.     wire [n-1:0] amount;    //current amount
  154.     wire [n-1:0] next;      //next amount
  155.     wire [n-1:0] value;     //value to add or subtract from amount
  156.     wire ovf;               //overflow - ignore for now
  157.  
  158.     //state register holds current amount
  159.     DFF #(n) amt(clk, next, amount);
  160.  
  161.     //select next state from 0, sum, or hold
  162.     Mux3 #(n) nsmux(amount, sum, {n{1'b0}}, selnext, next);
  163.  
  164.     //add or subtract a value from current amount
  165.     AddSub #(n) add(amount, value, sub, sum, ovf);
  166.  
  167.     //select the value to add or subtract
  168.     //p
  169.     Mux4 #(n) vmux(price, `NICKEL, `DIME, `QUARTER, selval, value);
  170.  
  171.     //comparators
  172.     wire enough = (amount >= price);
  173.     wire zero = (amount == 0);
  174. endmodule
  175.  
  176.  
  177.  
  178.  
  179.  
  180. module testVend;
  181.     reg clk, rst, nickel, dime, quarter, dispense, done;
  182.     reg [3:0] price;
  183.     wire serve, change;
  184.  
  185.     VendingMachine #(4) vm(clk, rst, nickel, dime, quarter, dispense, done, price,
  186.                             serve, change);
  187.    
  188.     //clock with period of 10 units
  189.     initial begin
  190.         clk = 1; #5 clk = 0;
  191.         forever begin
  192.             $display("%b %h %h %b %b",
  193.             {nickel, dime, quarter, dispense}, vm.vmc.state, vm.vmd.amount, serve, change);
  194.             #5 clk = 1; #5 clk = 0;
  195.         end
  196.     end
  197.  
  198.     //give prompt feedback
  199.     always @(posedge clk) begin
  200.         done = (serve | change);
  201.     end
  202.  
  203.     initial begin
  204.         rst = 1; {nickel, dime, quarter, dispense} = 4'b0;
  205.         price = `PRICE;
  206.         #25 rst = 0;
  207.         #10 {nickel, dime, quarter, dispense} = 4'b1000; //nickel 1
  208.         #10 {nickel, dime, quarter, dispense} = 4'b0100; //dime 3
  209.         #10 {nickel, dime, quarter, dispense} = 4'b0000; //nothing
  210.         #10 {nickel, dime, quarter, dispense} = 4'b0001; //try to dispense early
  211.         #10 {nickel, dime, quarter, dispense} = 4'b0010; //quarter 8
  212.         #10 {nickel, dime, quarter, dispense} = 4'b0010; //quarter 13
  213.         #10 {nickel, dime, quarter, dispense} = 4'b0000; //nothing
  214.         #10 {nickel, dime, quarter, dispense} = 4'b0001; //dispense 2
  215.         #10 dispense = 0;
  216.         #100 $stop;
  217.     end
  218. endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement