The short answer is that async/await is the underlying enabling factor for building core.async. If you have async/await, you could write the rest of core.async (or some other CSP) on top. It would include channels, buffers, and the rest of the API.
As for how Clojure implements them, Clojure’s go blocks are code-transforming macros. They convert the parking puts and takes (
I hope that answers your question! Thanks again.