/////////////////////////////////////////////////////////////////////// // // system module - 2023/2024 // // this is the top-level module which describes the complete system // /////////////////////////////////////////////////////////////////////// `include "options.sv" `ifdef clock_period // already defined - do nothing `else // this is a default frequency of 32.768kHz `define clock_period 30517.6ns // note that the calculation of the period is not perfectly accurate // - the inaccuracy here will most likely be less than that specified for the clock source itself `endif `ifdef num_modes // already defined - do nothing `else // default specification has 4 modes `define num_modes 4 `endif `ifdef led_num_digits // already defined - do nothing `else // default specification has 5 digits for the LED display `define led_num_digits 5 `endif `define STRINGIFY(x) `"x`" module system; timeunit 1ns; // this precision allows for clock_period/2 and clock_period/4 timeprecision 10ps; wire SegA, SegB, SegC, SegD, SegE, SegF, SegG, DP; wire [`led_num_digits - 1:0] nDigit; wire SCLK, SDIN, DnC, nSCE; wire SPICLK, MOSI, MISO, nAltCS; logic Mode, Trip; wire nMode, nTrip; event press_mode_button, press_trip_button; logic Button3; wire nButton3; event press_third_button; wire SDO; logic Clock, nReset, Test, SDI, ScanEnable; int mode_index; altimeter METER ( .SegA, .SegB, .SegC, .SegD, .SegE, .SegF, .SegG, .DP, .nDigit, `ifdef include_lcd .SCLK, .SDIN, .DnC, .nSCE, `endif .SPICLK, .MOSI, .MISO, .nAltCS, .nMode, .nTrip, `ifdef third_button .`third_button(nButton3), `endif `ifndef no_scan_signals .SDO, .Test, .SDI, `ifdef scan_enable .ScanEnable, `endif `endif .Clock, .nReset ); `ifdef sdf_file initial $sdf_annotate( `STRINGIFY(`sdf_file), METER ); `endif // the sports altimeter is supported by simulation models for the LED and LCD displays and for the sensor led_display LED ( .SegA, .SegB, .SegC, .SegD, .SegE, .SegF, .SegG, .DP, .nDigit ); `ifdef include_lcd lcd_display LCD ( .SCLK, .SDIN, .DnC, .nSCE, .nRES(nReset) ); `endif `ifdef use_simple_sensor simple_altimeter_sensor SENSOR ( .SCLK(SPICLK), .SDI(MOSI), .SDO(MISO), .CSB(nAltCS) ); `else ms5803_02ba SENSOR ( .SCLK(SPICLK), .SDI(MOSI), .SDO(MISO), .CSB(nAltCS) ); `endif // the inputs all pull down when active and high impedance at other times assign nMode = ( Mode ) ? '0 : 'z; assign nTrip = ( Trip ) ? '0 : 'z; assign nButton3 = ( Button3 ) ? '0 : 'z; `ifdef external_pullup pullup( weak0, weak1 )(nMode); pullup( weak0, weak1 )(nTrip); pullup( weak0, weak1 )(nButton3); `endif // display information about the design initial begin $display( "COMPILATION OK" ); $display( "CLOCK PERIOD IS ", `STRINGIFY(`clock_period) ); `ifdef include_lcd $display( "DISPLAY IS LED + LCD" ); `else $display( "DISPLAY IS LED ONLY" ); `endif $display( "This Sports Altimeter supports ", `STRINGIFY(`num_modes ), " modes:" ); `ifdef Mode0 $display( " Mode 0: ", `STRINGIFY(`Mode0) ); `endif `ifdef Mode1 $display( " Mode 1: ", `STRINGIFY(`Mode1) ); `endif `ifdef Mode2 $display( " Mode 2: ", `STRINGIFY(`Mode2) ); `endif `ifdef Mode3 $display( " Mode 3: ", `STRINGIFY(`Mode3) ); `endif `ifdef Mode4 $display( " Mode 4: ", `STRINGIFY(`Mode4) ); `endif `ifdef Mode5 $display( " Mode 5: ", `STRINGIFY(`Mode5) ); `endif `ifdef Mode6 $display( " Mode 6: ", `STRINGIFY(`Mode6) ); `endif $display( " (the altimeter will enter mode 0 on reset)"); end // define tasks to help with a simple stimulus task start_up_delay( ); begin `ifdef start_up_time #`start_up_time ; `endif end endtask always @(press_mode_button) begin `ifdef sanitise_input // delay until 1/4 of a clock period after a clock edge // - this should ensure that the clock delay to the // synchronisation D-types doesn't cause setup/hold violations @(posedge Clock ); #(`clock_period / 4) `endif Mode = 1; #0.1s `ifdef sanitise_input @(posedge Clock ); #(`clock_period / 4) `endif Mode = 0; mode_index = ( mode_index + 1 ) % `num_modes; end always @(press_trip_button) begin `ifdef sanitise_input // delay until 1/4 of a clock period after a clock edge // - this should ensure that the clock delay to the // synchronisation D-types doesn't cause setup/hold violations @(posedge Clock ); #(`clock_period / 4) `endif Trip = 1; #0.1s `ifdef sanitise_input @(posedge Clock ); #(`clock_period / 4) `endif Trip = 0; end always @(press_third_button) begin $display( "Press Third button" ); `ifdef sanitise_input // delay until 1/4 of a clock period after a clock edge // - this should ensure that the clock delay to the // synchronisation D-types doesn't cause setup/hold violations @(posedge Clock ); #(`clock_period / 4) `endif Button3 = 1; #0.1s `ifdef sanitise_input @(posedge Clock ); #(`clock_period / 4) `endif Button3 = 0; end `ifdef stimulus `include `STRINGIFY(`stimulus) `else initial begin Test = 0; SDI = 0; ScanEnable = 0; nReset = 0; #(`clock_period / 4) nReset = 1; end initial begin Clock = 0; #`clock_period forever begin Clock = 1; #(`clock_period / 2) Clock = 0; #(`clock_period / 2) Clock = 0; end end // Button stimulus // // This default stimulus represents a change in // mode once per second initial begin Mode = 0; Trip = 0; mode_index = 0; start_up_delay(); `ifdef basic_mode_change forever #1s -> press_mode_button; `endif end // Pressure stimulus // // This default stimulus represents initial pressure of 1013mb // followed by a steady reduction in pressure until a pressure of 500mb is reached initial begin SENSOR.pressure=1013; start_up_delay(); while ( SENSOR.pressure > 500 ) #0.1s SENSOR.pressure--; end `endif `ifdef special_monitor `include "monitor.sv" `endif `ifdef sim_time initial begin #`sim_time $stop; $finish; end `endif endmodule