Practice

Cutter Ramp Streamer

The blade head of a vinyl cutter cannot go from parked to cutting speed in one step; it tears the material. So every move starts with a ramp: 8 velocity words, streamed to the servo drive over a valid/ready handshake.

The previous implementation shipped to three customers before the field reports arrived. Ramps had missing steps or the same step twice, and one memorable unit drove the head into the rollers at full speed. The cause: whenever its buffer fills, the drive drops ready_i during the ramp, but the old source counted every word it presented as sent. The handshake rule it skipped is the one every datasheet states: a word transfers only on a cycle where valid_o and ready_i are both high. Until then, the source must hold valid_o high and keep the word rock steady.

Your task: build the source side, with the handshake done right. When the motion planner pulses go_i with a starting velocity on base_i, stream the 8 words base_i, base_i+1, ... base_i+7. Flag the final word with last_o, then go quiet.

Interface

PortDirectionTypeDescription
clk_iin1 bitClock
rst_iin1 bitSynchronous reset (active high)
go_iin1 bitStart pulse from the motion planner
base_iin8-bit vectorStarting velocity, captured when go_i is taken
ready_iin1 bitDrive can accept a word this cycle
valid_oout1 bitWord on data_o is valid
data_oout8-bit vectorVelocity word base_i + k (wraps mod 256)
last_oout1 bitHigh while word 8 of 8 is presented

Behavior

  • Idle: valid_o = 0 and last_o = 0; data_o is meaningless and unchecked while valid_o = 0
  • go_i = 1 sampled at a clock edge while idle starts a burst: from the next cycle, valid_o = 1 and data_o = base_i as captured at that edge
  • A word transfers at each clock edge where valid_o = 1 and ready_i = 1; the next cycle presents the next word, data_o = base_i + k for word k (wrapping mod 256)
  • While valid_o = 1 and ready_i = 0, every output holds exactly: valid_o, data_o, and last_o must not change
  • last_o = 1 exactly while the eighth word (base_i + 7) is presented, stalled or not
  • After the eighth word transfers, the block returns to idle from the next cycle; a go_i on that first idle cycle starts a new burst
  • go_i is ignored whenever a burst is in progress; base_i changes mid-burst are ignored too
  • rst_i = 1 at a clock edge aborts everything: idle from the next cycle

What the bench checks

  • The testbench checks valid_o and last_o on every cycle and data_o on every cycle where valid_o should be 1
  • A full-rate burst must present eight consecutive values, assert last_o only on the eighth, then return to idle
  • Stalls on the first, middle, and final words must hold outputs steady; the stalled ramp also wraps from FF to 00
  • A new go_i pulse and changes to base_i during a burst must not alter that burst
  • Reset during a stalled burst must abort it immediately and keep the source idle afterward
  • A go_i held across the final transfer must be ignored there, then start the next burst from the following idle cycle

Constraints

TIMING: everything is synchronous to clk_i; outputs may only change at clock edges.

SCOPE: this models the source side of the handshake only. The servo drive and its buffer live behind ready_i, and the blade mechanics are out of scope.

The burst length is fixed at 8 and the word values are base_i + k mod 256, so no memory is involved.

Do not add ports.

Loading editor...

Click Run to execute your code. Output will appear here.